Bagikan melalui


WriteableBitmap.PixelBuffer Properti

Definisi

Mendapatkan akses untuk buffer langsung tempat setiap piksel WriteableBitmap ditulis.

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

Nilai Properti

Referensi ke buffer piksel.

Contoh

Contoh kode ini menggunakan properti PixelBuffer dari WriteableBitmap untuk menulis ke konten pikselnya.

Contoh C# berasal dari sampel kode yang lebih besar—sampel gambar SDK XAML. Kode C# yang ditampilkan adalah bagian dari skenario transcoding yang akhirnya menggunakan WriteableBitmap sebagai nilai Image.Source , dan menampilkan gambar.

Contoh dalam bahasa lain sedikit lebih terlingkup dan/atau mandiri.

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;

Keterangan

Catatan

Gunakan Pemilih bahasa (di dekat judul) untuk memilih bahasa pemrograman untuk contoh kode.

IBuffer yang dikembalikan oleh PixelBuffer tidak dapat ditulis secara langsung. Tetapi Anda dapat menggunakan teknik khusus bahasa untuk menulis ke konten piksel yang mendasar di buffer.

  • Untuk mengakses konten piksel dari C# atau Microsoft Visual Basic, Anda dapat menggunakan metode WindowsRuntimeBufferExtensions.AsStream untuk mengakses buffer yang mendasarinya sebagai aliran. Ini ditampilkan dalam contoh kode C#.
  • Untuk mengakses konten piksel dari C++/WinRT, Anda memiliki tiga alternatif. Selama Anda tidak using namespace winrt;, maka Anda dapat menyertakan file robuffer.h header SDK untuk membawa definisi antarmuka IBufferByteAccess COM. Namun, karena using namespace winrt; sangat umum, Anda dapat menentukan antarmuka IBufferByteAccess di satu tempat di proyek Anda (lihat contoh kode C++/WinRT untuk melihat caranya). Setelah IBufferByteAccess ditentukan, menggunakan salah satu dari dua teknik tersebut, Anda dapat mengkueri PixelBuffer untuk instans IBufferByteAccess. Anda kemudian memanggil metode IBufferByteAccess::Buffer untuk mengambil pointer ke buffer byte yang mewakili konten piksel. Ini ditampilkan dalam contoh kode C++/WinRT. Alternatif ketiga (juga ditampilkan dalam contoh kode C++/WinRT) adalah menghindari penggunaan IBufferByteAccess sama sekali dengan mengambil uint8_t* yang dikembalikan dari fungsi pembantu yang dapat Anda panggil dengan WriteableBitmap.PixelBuffer().data().
  • Untuk mengakses konten piksel dari C++/CX, Anda dapat mengkueri PixelBuffer untuk antarmuka IBufferByteAccess, yang merupakan antarmuka COM. Sertakan robuffer.h. Anda kemudian dapat memanggil metode IBufferByteAccess::Buffer untuk mengambil pointer ke buffer byte yang mewakili konten piksel. Ini ditampilkan dalam contoh kode C++/CX.

Berlaku untuk

Lihat juga