Compartir a través de


WriteableBitmap.PixelBuffer Propiedad

Definición

Obtiene un acceso al búfer directo en el que se escribe cada píxel del objeto WriteableBitmap .

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

Valor de propiedad

Referencia al búfer de píxeles.

Ejemplos

En este ejemplo de código se usa la propiedad PixelBuffer de WriteableBitmap para escribir en su contenido de píxeles.

El ejemplo de C# procede de un ejemplo de código más grande: el ejemplo de imágenes XAML del SDK. El código de C# que se muestra forma parte de un escenario de transcodificación que finalmente usa WriteableBitmap como un valor Image.Source y muestra la imagen.

Los ejemplos de los otros idiomas son un poco más de ámbito y/o autocontenido.

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;

Comentarios

El objeto IBuffer devuelto por PixelBuffer no se puede escribir directamente. Pero puede usar técnicas específicas del lenguaje para escribir en el contenido de píxeles subyacente en el búfer.

  • Para acceder al contenido de píxeles desde C# o Microsoft Visual Basic, puede usar el método WindowsRuntimeBufferExtensions.AsStream para acceder al búfer subyacente como una secuencia. Esto se muestra en el ejemplo de código de C#.
  • Para acceder al contenido de píxeles desde C++/WinRT, tiene tres alternativas. Siempre que no using namespace winrt;sea , puede incluir el archivo robuffer.h de encabezado del SDK para incluir la definición de la interfaz COM de IBufferByteAccess . Sin embargo, como using namespace winrt; es muy común, también puede definir la interfaz IBufferByteAccess en un solo lugar del proyecto (consulte el ejemplo de código de C++/WinRT para ver cómo). Una vez definido IBufferByteAccess , con cualquiera de esas dos técnicas, puede consultar PixelBuffer para una instancia de IBufferByteAccess. A continuación, llama al método IBufferByteAccess::Buffer para recuperar un puntero al búfer de bytes que representa el contenido de píxeles. Esto se muestra en el ejemplo de código de C++/WinRT. La tercera alternativa (que también se muestra en el ejemplo de código de C++/WinRT) es evitar el uso de IBufferByteAccess por completo recuperando el uint8_t* que se devuelve de una función auxiliar a la que se puede llamar con WriteableBitmap.PixelBuffer().data().
  • Para acceder al contenido de píxeles desde C++/CX, puede consultar PixelBuffer para la interfaz IBufferByteAccess, que es una interfaz COM. Incluya robuffer.h. A continuación, puede llamar al método IBufferByteAccess::Buffer para recuperar un puntero al búfer de bytes que representa el contenido de píxeles. Esto se muestra en el ejemplo de código de C++/CX.

Se aplica a

Consulte también