locked
How to create a 'IWICBitmapDecoder' using 'StorageFile' RRS feed

  • Question

  • I am unable to create a decoder using StorageFile->Path. I get access errors. I am using WICFactory to create this decoder. My ultimate goal is to crate 'BitMapRenderingTarget' so that I can manipulate bit map file that's picked by user (using pickers) and represented by 'StorageFile'.

    All Metro App examples point to a bit map files that are part of the project. Looks like there is no issue in accessing those files. I am having problem with files chose using 'File Picker'. Any example or tips?

     

    Thanks

    PB

    Tuesday, October 11, 2011 11:52 PM

Answers

  • Actually I meant something like this:

        FileOpenPicker^ openPicker = ref new FileOpenPicker();
        openPicker->ViewMode = PickerViewMode::Thumbnail;
        openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
        openPicker->FileTypeFilter->Append(".jpg");
        openPicker->FileTypeFilter->Append(".jpeg");
        openPicker->FileTypeFilter->Append(".png");
        auto pickOperation = openPicker->PickSingleFileAsync();
        TextBlock^ result = Scenario1FileName;
        pickOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([result](IAsyncOperation<StorageFile^> ^operation)
        {
            auto file = operation->GetResults();
            if (file)
            {
    			auto copyOperation = file->CopyAsync((Windows::Storage::ApplicationData::Current)->TemporaryFolder, file->FileName, Windows::Storage::NameCollisionOption::ReplaceExisting);
    			copyOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([result](IAsyncOperation<StorageFile^> ^copyOp)
    			{
    				auto copiedFile = copyOp->GetResults();
    
    				ComPtr<IWICStream> pStream = NULL;
    				wicFactory->CreateStream(&pStream);
            
    				pStream->InitializeFromFilename(copiedFile ->Data(), .......);
    			});
    			copyOperation->Start();
            }
            else
            {
                result->Text = "File was not returned";
            }
        });
        pickOperation->Start();
    


    • Proposed as answer by Raman Sharma Friday, October 14, 2011 6:36 AM
    • Marked as answer by __PB Friday, October 14, 2011 4:07 PM
    Friday, October 14, 2011 6:35 AM
  • ComPtr<IWICStream> fileStrm;
    DX::ThrowIfFailed(m_wicFactory->CreateStream(&fileStrm));
    DX::ThrowIfFailed(fileStrm->InitializeFromFilename(imgFileNameWithPath->Data(), GENERIC_READ));
    ComPtr<IWICBitmapDecoder> decoder;
    DX::ThrowIfFailed(m_wicFactory->CreateDecoderFromStream(fileStrm.Get(),	NULL, 
    						WICDecodeMetadataCacheOnDemand, &decoder)
    						);
    

    Does it help you SliconBender? 
    Monday, December 5, 2011 10:54 PM

All replies

  • Hi PB,

    The Simple Imaging Sample shows reading files using the FilePicker.  When do you get the access error?

    http://code.msdn.microsoft.com/windowsapps/Simple-Imaging-Sample-a2dec2b0/sourcecode?fileId=44000&pathId=446912091

    -Jeff

     


    Jeff Sanders (MSFT)
    Wednesday, October 12, 2011 12:37 PM
    Moderator
  • Files in Pictures and Documents libraries may only be accessed via Windows Runtime API.  If you try to access them using regular Win32 or COM API, you may get access denied. 

    However your app has unrestricted read/write access to the app-local folder:

    Windows.Storage.ApplicationData.current.temporaryFolder

     

    You might want to copy the selected file to this folder (using the copyAsync method) and try again.

    This has worked for me.

    Thanks

    Raman Sharma, Visual C++

    • Proposed as answer by Raman Sharma Thursday, October 13, 2011 10:57 PM
    Thursday, October 13, 2011 10:57 PM
  • Raman,

            Thanks for your reply.

            Here is my use case, my users pick picture using a picker. So picker returns me the 'StorageFile' object of the picked picture(s). I would like to modify those pictures, for that I used Direct2D APIs (BitmapRenderTarget). These Direct2D APIs use different stream objects. So I was trying to open a file using normal way and got access denied exception and guessed "Metro apps do not have access to these folders" and it makes sense.

            I should have asked my question differently here it is

            How to convert 'IRandomAccess^' to 'IWICStream* or IStream*' and vice versa.

    Thanks

    PB


    • Edited by __PB Thursday, October 13, 2011 11:15 PM
    Thursday, October 13, 2011 11:10 PM
  • I understand your scenario.  What I am saying is that you can try something like this:

    • Let the user pick a file which returns you StorageFile
    • Copy this file to the App-Local folder
    • Get the physical path of the the app-local file
    • Using this path, construct a WICStream and apply whatever D2D API you want to

    If you do it this way, you may not need to worry about 'IRandomAccess^' at all.

    Not sure if the extra copy operation is a problem for you though.

    Thanks
    Raman Sharma, Visual C++

    Friday, October 14, 2011 12:25 AM
  • Raman,

             Thank you, what path should I pass to my WICStream (is it like app-domain:/img.jpg or img.jpg). Not sure how WICStream looks for the file (I use WICStream->InitializeFromFilename("Images/imgjg", ...) and works). img.jpg is part of a project folder that's why I do not see access restrictions.

    Thanks
    PB

    Friday, October 14, 2011 5:28 AM
  • Actually I meant something like this:

        FileOpenPicker^ openPicker = ref new FileOpenPicker();
        openPicker->ViewMode = PickerViewMode::Thumbnail;
        openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
        openPicker->FileTypeFilter->Append(".jpg");
        openPicker->FileTypeFilter->Append(".jpeg");
        openPicker->FileTypeFilter->Append(".png");
        auto pickOperation = openPicker->PickSingleFileAsync();
        TextBlock^ result = Scenario1FileName;
        pickOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([result](IAsyncOperation<StorageFile^> ^operation)
        {
            auto file = operation->GetResults();
            if (file)
            {
    			auto copyOperation = file->CopyAsync((Windows::Storage::ApplicationData::Current)->TemporaryFolder, file->FileName, Windows::Storage::NameCollisionOption::ReplaceExisting);
    			copyOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([result](IAsyncOperation<StorageFile^> ^copyOp)
    			{
    				auto copiedFile = copyOp->GetResults();
    
    				ComPtr<IWICStream> pStream = NULL;
    				wicFactory->CreateStream(&pStream);
            
    				pStream->InitializeFromFilename(copiedFile ->Data(), .......);
    			});
    			copyOperation->Start();
            }
            else
            {
                result->Text = "File was not returned";
            }
        });
        pickOperation->Start();
    


    • Proposed as answer by Raman Sharma Friday, October 14, 2011 6:36 AM
    • Marked as answer by __PB Friday, October 14, 2011 4:07 PM
    Friday, October 14, 2011 6:35 AM
  • Raman,

             Thank you (you mean to say copiesFile->Path->Data()), this may work, will try and update this thread.

    Thanks

    Sai


    • Edited by __PB Friday, October 14, 2011 4:14 PM
    Friday, October 14, 2011 4:07 PM
  • Yes, I meant copiedFile ->Path->Data()
    Friday, October 14, 2011 5:19 PM
  • Sorry I am a bit of a novice in using the ms apis.  How does one go from having a IWicStream to an IStream that can be passed into..

     

    wicFactory->CreateDecoderFromStream( IStream* stream, NULL, WICDecodeMetadataCacheOnDemand, &decoder);

     

    I have tried passing in that pStream above and the compiler does not like that at all.

    Sunday, December 4, 2011 8:43 PM
  • ComPtr<IWICStream> fileStrm;
    DX::ThrowIfFailed(m_wicFactory->CreateStream(&fileStrm));
    DX::ThrowIfFailed(fileStrm->InitializeFromFilename(imgFileNameWithPath->Data(), GENERIC_READ));
    ComPtr<IWICBitmapDecoder> decoder;
    DX::ThrowIfFailed(m_wicFactory->CreateDecoderFromStream(fileStrm.Get(),	NULL, 
    						WICDecodeMetadataCacheOnDemand, &decoder)
    						);
    

    Does it help you SliconBender? 
    Monday, December 5, 2011 10:54 PM
  • Yes, thanks!
    Tuesday, December 6, 2011 12:21 AM
  • this code sample is out of date and is not as efficient as it can be. see the file access sample to learn how to access files

    http://code.msdn.microsoft.com/windowsapps/File-access-sample-d723e597/sourcecode?fileId=44739&pathId=182690253

    Monday, July 23, 2012 5:31 PM