Answered by:
How to create a 'IWICBitmapDecoder' using 'StorageFile'

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?- Edited by __PB Monday, December 5, 2011 10:56 PM
- Proposed as answer by PixelWhisperer Tuesday, December 6, 2011 12:21 AM
- Marked as answer by Jeff SandersMicrosoft employee, Moderator Tuesday, December 6, 2011 7:34 PM
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?
-Jeff
Jeff Sanders (MSFT)Wednesday, October 12, 2011 12:37 PMModerator -
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
PBFriday, 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?- Edited by __PB Monday, December 5, 2011 10:56 PM
- Proposed as answer by PixelWhisperer Tuesday, December 6, 2011 12:21 AM
- Marked as answer by Jeff SandersMicrosoft employee, Moderator Tuesday, December 6, 2011 7:34 PM
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
Monday, July 23, 2012 5:31 PM