WriteableBitmap.PixelBuffer Proprietà
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
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 filerobuffer.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'oggettouint8_t*
restituito da una funzione helper che è possibile chiamare conWriteableBitmap.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.