WriteableBitmap.PixelBuffer Proprietà

Definizione

Ottiene un accesso per il buffer diretto in cui ogni pixel della mappa WriteableBitmap viene scritta.

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

Valore della proprietà

Riferimento al buffer pixel.

Esempio

Questo esempio di codice usa la proprietà PixelBuffer di WriteableBitmap per scrivere nel relativo contenuto pixel.

L'esempio C# proviene da un esempio di codice più grande, ovvero l'esempio di immagini XAML SDK. Il codice C# illustrato fa parte di uno scenario di transcoding che alla fine usa WriteableBitmap come valore Image.Source e visualizza l'immagine.

Gli esempi nelle altre lingue sono un po' più ambiti e/o autonomi.

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;

Commenti

L'IBuffer restituito da PixelBuffer non può essere scritto direttamente. È tuttavia possibile usare tecniche specifiche del linguaggio per scrivere nel contenuto del pixel sottostante nel buffer.

  • Per accedere al contenuto pixel da C# o Microsoft Visual Basic, è possibile usare il metodo WindowsRuntimeBufferExtensions.AsStream per accedere al buffer sottostante come flusso. Questa operazione viene illustrata nell'esempio di codice C#.
  • Per accedere al contenuto pixel da C++/WinRT, sono disponibili tre alternative. Purché non using namespace winrt;si sia , è possibile includere il file robuffer.h di intestazione SDK per inserire la definizione dell'interfaccia COM IBufferByteAccess . Tuttavia, poiché using namespace winrt; è molto comune, è possibile definire in alternativa l'interfaccia IBufferByteAccess in un'unica posizione nel progetto (vedere l'esempio di codice C++/WinRT per vedere come). Dopo aver definito IBufferByteAccess , usando una di queste due tecniche, è possibile eseguire una query su PixelBuffer per un'istanza di IBufferByteAccess. Si chiama quindi il metodo IBufferByteAccess::Buffer per recuperare un puntatore al buffer di byte che rappresenta il contenuto del pixel. Questo è illustrato nell'esempio di codice C++/WinRT. La terza alternativa (illustrata anche nell'esempio di codice C++/WinRT) consiste nell'evitare di usare completamente IBufferByteAccess recuperando l'oggetto uint8_t* restituito da una funzione helper che è possibile chiamare con WriteableBitmap.PixelBuffer().data().
  • Per accedere al contenuto pixel da C++/CX, è possibile eseguire query su PixelBuffer per l'interfaccia IBufferByteAccess, ovvero un'interfaccia COM. Includere robuffer.h. È quindi possibile chiamare il metodo IBufferByteAccess::Buffer per recuperare un puntatore al buffer di byte che rappresenta il contenuto del pixel. Viene illustrato nell'esempio di codice C++/CX.

Si applica a

Vedi anche