Share via


WriteableBitmap.PixelBuffer Eigenschaft

Definition

Ruft einen Zugriff auf den direkten Puffer ab, in den jedes Pixel der WriteableBitmap geschrieben wird.

public:
 property IBuffer ^ PixelBuffer { IBuffer ^ get(); };
IBuffer PixelBuffer();
public IBuffer PixelBuffer { get; }
var iBuffer = writeableBitmap.pixelBuffer;
Public ReadOnly Property PixelBuffer As IBuffer

Eigenschaftswert

Ein Verweis auf den Pixelpuffer.

Beispiele

In diesem Codebeispiel wird die PixelBuffer-Eigenschaft von WriteableBitmap verwendet, um in den zugehörigen Pixelinhalt zu schreiben.

Das C#-Beispiel stammt aus einem größeren Codebeispiel– dem SDK-XAML-Beispiel für Bilder. Der angezeigte C#-Code ist Teil eines Transcodierungsszenarios, das schließlich writeableBitmap als Image.Source-Wert verwendet und das Bild anzeigt.

Die Beispiele in den anderen Sprachen sind etwas abgegrenzt und/oder eigenständiger.

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;

Hinweise

Der von PixelBuffer zurückgegebene IBuffer kann nicht direkt in geschrieben werden. Sie können jedoch sprachspezifische Techniken verwenden, um in den zugrunde liegenden Pixelinhalt im Puffer zu schreiben.

  • Um über C# oder Microsoft Visual Basic auf den Pixelinhalt zuzugreifen, können Sie die WindowsRuntimeBufferExtensions.AsStream-Methode verwenden, um auf den zugrunde liegenden Puffer als Stream zuzugreifen. Dies wird im C#-Codebeispiel gezeigt.
  • Um über C++/WinRT auf den Pixelinhalt zuzugreifen, haben Sie drei Alternativen. Solange Sie nicht using namespace winrt;sind, können Sie die SDK-Headerdatei robuffer.h einschließen, um die Definition der IBufferByteAccess-COM-Schnittstelle einzubinden. Da using namespace winrt; jedoch sehr häufig ist, können Sie alternativ die IBufferByteAccess-Schnittstelle an einer Stelle in Ihrem Projekt definieren (siehe C++/WinRT-Codebeispiel, um zu sehen, wie das geht). Nachdem IBufferByteAccess definiert wurde, können Sie mit einer dieser beiden Verfahren PixelBuffer nach einer instance von IBufferByteAccess abfragen. Anschließend rufen Sie die IBufferByteAccess::Buffer-Methode auf, um einen Zeiger auf den Bytespuffer abzurufen, der den Pixelinhalt darstellt. Dies wird im C++/WinRT-Codebeispiel gezeigt. Die dritte Alternative (auch im C++/WinRT-Codebeispiel gezeigt) besteht darin, die Verwendung von IBufferByteAccess vollständig zu vermeiden, indem Sie die uint8_t* von einer Hilfsfunktion zurückgegebene abrufen, die Sie mit WriteableBitmap.PixelBuffer().data()aufrufen können.
  • Um über C++/CX auf den Pixelinhalt zuzugreifen, können Sie PixelBuffer für die IBufferByteAccess-Schnittstelle abfragen, bei der es sich um eine COM-Schnittstelle handelt. Schließen Sie robuffer.h ein. Anschließend können Sie die IBufferByteAccess::Buffer-Methode aufrufen, um einen Zeiger auf den Bytespuffer abzurufen, der den Pixelinhalt darstellt. Dies wird im C++/CX-Codebeispiel gezeigt.

Gilt für:

Weitere Informationen