WriteableBitmap.PixelBuffer Propriété
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Obtient un accès pour la mémoire tampon directe dans laquelle chaque pixel du WriteableBitmap est écrit.
public:
property IBuffer ^ PixelBuffer { IBuffer ^ get(); };
IBuffer PixelBuffer();
public IBuffer PixelBuffer { get; }
var iBuffer = writeableBitmap.pixelBuffer;
Public ReadOnly Property PixelBuffer As IBuffer
Valeur de propriété
Référence à la mémoire tampon de pixels.
Exemples
Cet exemple de code utilise la propriété PixelBuffer de WriteableBitmap pour écrire dans son contenu de pixels.
L’exemple C# provient d’un exemple de code plus volumineux: l’exemple d’images XAML du SDK. Le code C# indiqué fait partie d’un scénario de transcodage qui utilise finalement writeableBitmap comme valeur Image.Source et affiche l’image.
Les exemples dans les autres langues sont un peu plus étendus et/ou autonomes.
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// Scale image to appropriate size
BitmapTransform transform = new BitmapTransform() {
ScaledWidth = Convert.ToUInt32(Scenario4WriteableBitmap.PixelWidth),
ScaledHeight = Convert.ToUInt32(Scenario4WriteableBitmap.PixelHeight)
};
PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage
);
// An array containing the decoded image data, which could be modified before being displayed
byte[] sourcePixels = pixelData.DetachPixelData();
// Open a stream to copy the image contents to the WriteableBitmap's pixel buffer
using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream())
{
await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length);
}
}
// You'll need to add the Pictures Library capability to your Package.appxmanifest file.
// MainPage.xaml
...
<Image x:Name="anyExampleImage" Width="100" Height="100"/>
...
// pch.h
...
#include <winrt/Windows.Graphics.Imaging.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da")) IBufferByteAccess : ::IUnknown
{
virtual HRESULT __stdcall Buffer(uint8_t** value) = 0;
};
...
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
Windows::Foundation::IAsyncAction ClickHandler(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
private:
Windows::UI::Xaml::Media::Imaging::WriteableBitmap m_writeableBitmap{ nullptr };
};
...
// MainPage.cpp
...
Windows::Foundation::IAsyncAction MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
uint32_t scaledSize = 100;
m_writeableBitmap = Windows::UI::Xaml::Media::Imaging::WriteableBitmap(scaledSize, scaledSize);
Windows::Storage::StorageFolder picturesFolder{ Windows::Storage::KnownFolders::PicturesLibrary() };
auto anyExampleImageFile{ co_await picturesFolder.GetFileAsync(L"anyexampleimage.png") };
Windows::Storage::Streams::IRandomAccessStream fileStream{ co_await anyExampleImageFile.OpenAsync(Windows::Storage::FileAccessMode::Read) };
auto decoder{ co_await Windows::Graphics::Imaging::BitmapDecoder::CreateAsync(fileStream) };
// Scale the image to the appropriate size.
Windows::Graphics::Imaging::BitmapTransform transform;
transform.ScaledWidth(scaledSize);
transform.ScaledHeight(scaledSize);
Windows::Graphics::Imaging::PixelDataProvider pixelData{ co_await decoder.GetPixelDataAsync(
Windows::Graphics::Imaging::BitmapPixelFormat::Bgra8, // WriteableBitmap uses BGRA format
Windows::Graphics::Imaging::BitmapAlphaMode::Straight,
transform,
Windows::Graphics::Imaging::ExifOrientationMode::IgnoreExifOrientation, // This sample ignores Exif orientation
Windows::Graphics::Imaging::ColorManagementMode::DoNotColorManage
) };
// An array containing the decoded image data, which could be modified before being displayed
winrt::com_array<uint8_t> sourcePixels{ pixelData.DetachPixelData() };
// COMMENT OUT EXACTLY ONE OF TECHNIQUE 1/2
// TECHNIQUE 1; QI for IBufferByteAccess.
auto bufferByteAccess{ m_writeableBitmap.PixelBuffer().as<::IBufferByteAccess>() };
uint8_t * pTargetBytes{ nullptr };
bufferByteAccess->Buffer(&pTargetBytes);
// TECHNIQUE 2; use a C++/WinRT helper function (and delete the definition of IBufferByteAccess in pch.h).
//uint8_t * pTargetBytes{ m_writeableBitmap.PixelBuffer().data() };
for (auto & element : sourcePixels)
{
*(pTargetBytes++) = element;
}
anyExampleImage().Source(m_writeableBitmap);
}
...
// pch.h
...
#include <robuffer.h>
...
// MainPage.xaml.cpp
auto writeableBitmap{ ref new Windows::UI::Xaml::Media::Imaging::WriteableBitmap(100, 100) };
::IUnknown* pUnk{ reinterpret_cast<IUnknown*>(writeableBitmap->PixelBuffer) };
Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
HRESULT hr{ pUnk->QueryInterface(IID_PPV_ARGS(&bufferByteAccess)) };
byte *pBuffer{ nullptr };
bufferByteAccess->Buffer(&pBuffer);
// Now, write into the WriteableBitmap by using pBuffer. For example, make the first pixel red.
*pBuffer = 0xFF; ++pBuffer;
*pBuffer = 0xFF; ++pBuffer;
*pBuffer = 0x0; ++pBuffer;
*pBuffer = 0x0;
Remarques
L’IBuffer retourné par PixelBuffer ne peut pas être écrit directement dans. Toutefois, vous pouvez utiliser des techniques spécifiques au langage pour écrire dans le contenu de pixels sous-jacent dans la mémoire tampon.
- Pour accéder au contenu des pixels à partir de C# ou Microsoft Visual Basic, vous pouvez utiliser la méthode WindowsRuntimeBufferExtensions.AsStream pour accéder à la mémoire tampon sous-jacente en tant que flux. Cela est illustré dans l’exemple de code C#.
- Pour accéder au contenu des pixels à partir de C++/WinRT, vous avez trois alternatives. Tant que vous n’êtes pas
using namespace winrt;
, vous pouvez inclure le fichierrobuffer.h
d’en-tête du KIT de développement logiciel (SDK) pour apporter la définition de l’interface COM IBufferByteAccess . Toutefois, étant donné queusing namespace winrt;
c’est très courant, vous pouvez également définir l’interface IBufferByteAccess dans un seul emplacement dans votre projet (consultez l’exemple de code C++/WinRT pour savoir comment procéder). Une fois IBufferByteAccess défini, à l’aide de l’une de ces deux techniques, vous pouvez interroger PixelBuffer pour obtenir une instance de IBufferByteAccess. Vous appelez ensuite la méthode IBufferByteAccess::Buffer pour récupérer un pointeur vers la mémoire tampon d’octets qui représente le contenu des pixels. Cela est illustré dans l’exemple de code C++/WinRT. La troisième alternative (également présentée dans l’exemple de code C++/WinRT) consiste à éviter d’utiliser IBufferByteAccess en récupérant leuint8_t*
qui est retourné à partir d’une fonction d’assistance que vous pouvez appeler avecWriteableBitmap.PixelBuffer().data()
. - Pour accéder au contenu des pixels à partir de C++/CX, vous pouvez interroger PixelBuffer pour l’interface IBufferByteAccess, qui est une interface COM. Incluez
robuffer.h
. Vous pouvez ensuite appeler la méthode IBufferByteAccess::Buffer pour récupérer un pointeur vers la mémoire tampon d’octets qui représente le contenu des pixels. Cela est illustré dans l’exemple de code C++/CX.