Share via


WriteableBitmap.PixelBuffer Propriété

Définition

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

Notes

Utilisez le sélecteur de langage (près du titre) pour choisir un langage de programmation pour l’exemple de code.

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 fichier robuffer.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é que using 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 le uint8_t* qui est retourné à partir d’une fonction d’assistance que vous pouvez appeler avec WriteableBitmap.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.

S’applique à

Voir aussi