Partager 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

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