Как создать WritebleBitmap из образа ресурса с помощью C++ для приложения Windows Metro?

Я могу легко создать BitmapImage из файла изображения ресурса JPG, используя следующий код...

Windows::Foundation::Uri^ uri = ref new Windows::Foundation::Uri(L"ms-appx:///Hippo.JPG");
Imaging::BitmapImage^ image = ref new Imaging::BitmapImage(uri);

Но WritableBitmap не принимает Uri. Я вижу метод SetSource, но для этого нужен IRandomaccessStream, а не Uri. И я понятия не имею, как создать его из файла JPG. Я искал в сети снова и снова, но не мог найти прямого прямого ответа. Любая помощь будет принята с благодарностью.

Я хочу что-то вроде этого...

Windows::UI::Xaml::Media::Imaging::WriteableBitmap image = ref new Windows::UI::Xaml::Media::Imaging::WriteableBitmap();
image->SetSource(somehowGetRandomAccessStreamFromUri);

Но как мне получить экземпляр IRandomaccessStream из uri? Я начал работать над приложением C++ Metro только сегодня, поэтому могу ошибаться, но мне кажется, что оно слишком сложное из-за слишком большого количества очистки лука.


person abix    schedule 21.07.2012    source источник


Ответы (1)


В С# вы бы сделали что-то вроде

var storageFile = await Package.Current.InstalledLocation.GetFileAsync(relativePath.Replace('/', '\\'));
var stream = await storageFile.OpenReadAsync();
var wb = new WriteableBitmap(1, 1);
wb.SetSource(stream);

Я думаю, что в C++/CX вы бы сделали что-то вроде этого:

#include <ppl.h>
#include <ppltasks.h>

...

Concurrency::task<Windows::Storage::StorageFile^> getFileTask
    (Package::Current->InstalledLocation->GetFileAsync(L"Assets\\MyImage.jpg"));

auto getStreamTask = getFileTask.then(
    [] (Windows::Storage::StorageFile ^storageFile)
    {
        return storageFile->OpenReadAsync();
    });

getStreamTask.then(
    [] (Windows::Storage::Streams::IRandomAccessStreamWithContentType^ stream)
    {
        auto wb = ref new Windows::UI::Xaml::Media::Imaging::WriteableBitmap(1, 1);
        wb->SetSource(stream);
    });
person Filip Skakun    schedule 21.07.2012
comment
Спасибо Филипп, это сработало как шарм. Я должен был сделать одно маленькое изменение, хотя. Изменил LAssets\\MyImage.jpg на LMyImage.jpg, так как по какой-то причине я получал исключение недопустимого аргумента. - person abix; 22.07.2012
comment
Наконец-то выяснилось, что содержимое пикселей WritableBitmap недоступно ни для чтения, ни для записи :( Я могу получить указатель IBuffer, который не предоставляет доступ к своему буферу! В любом случае, это отдельный вопрос. - person abix; 22.07.2012
comment
@abix В C# я использовал AsStream для преобразования буфера в поток ввода-вывода. Это должно быть выполнимо и на C++. Ознакомьтесь с примерами C# здесь. - person Filip Skakun; 22.07.2012
comment
Я нашел решение на другом форуме, например, как получить байт* из IBuffer... IUnknown* pUnk = reinterpret_cast‹IUnknown*›(writableImage-›PixelBuffer); IBufferByteAccess* pBufferByteAccess = nullptr; HRESULT hr = pUnk->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess)); байт *пиксели = nullptr; pBufferByteAccess->Буфер(&пиксели); - person abix; 22.07.2012