How to get RGB value of a pixel in WinRT

后端 未结 2 1012
[愿得一人]
[愿得一人] 2021-01-16 12:45

I am trying to get the RGB value of each pixel in WinRT app. I can access an array of bytes containing PixelData but I don\'t know how to work with that so how

相关标签:
2条回答
  • 2021-01-16 13:12

    Since you have a RGB image, tempBuffer[k + 0] is the red channel, tempBuffer[k + 1] is the green channel, and tempBuffer[k + 2] is the blue channel, i.e. tempBuffer is a 1D array. If you were looping over all the pixels, the pseudo code for this would be:

    for i = 0 to height - 1
        for j = 0 to width - 1
            k = (i * width + j) * 3
            r, g, b = tempBuffer[k + 0], tempBuffer[k + 1], tempBuffer[k + 2]
    
    0 讨论(0)
  • 2021-01-16 13:15

    Since the Marshal class isn't available on WinRT - the most performant way to proceed would be to use a SafeMemoryMappedViewHandle (SafeBuffer).

    This method can also handle pixelformats with multi-byte components without needing to use a BinaryReader and reading it component by component (RGBA16 with 16 bits per component). Find out what the pixel format is using the decoder's BitmapPixelFormat property and use the appropriately declared structure.

        // declare more of these appropriately laid
        // out structures for different pixel formats
        struct RGBA16
        {
            public uint R;
            public uint G;
            public uint B;
            public uint A;
        }
    
        struct RGBA8
        {
            public byte R;
            public byte G;
            public byte B;
            public byte A;
        }
    
        struct BRGA8
        {
            public byte B;
            public byte G;
            public byte R;
            public byte A;
        }
        ...
    
        var handle = GCHandle.Alloc(tempBuffer /* the raw byte[] */, GCHandleType.Pinned);
        try
        {
            var ptr = handle.AddrOfPinnedObject();
            var safeBuffer = new SafeMemoryMappedViewHandle(true /* I believe DetachPixelData returns a copy? false otherwise  */)
            safeBuffer.SetHandle(ptr);
    
            #if STREAM_PROCESSING
                // pixel by pixel
                int offset = 0;
                for (int i = 0; i < width * height; i++)
                {
                    var pixel = safeBuffer.Read<RGBA16>(offset);
                    offset += RGB24bpp.Size;
                }
            #else
                // Read it all in at once - this makes a copy
                var pixels = new RGBA16[width * height];
                safeBuffer.ReadArray<RGBA16>(0, pixels, 0, width * height);
            #endif
        }
        finally
        {
            safeBuffer.Dispose();
            handle.Free;
        }
    

    Note: This method can also be a replacement for any operation that requires Marshal.PtrToStructure or some such equivalent on WinRT.

    0 讨论(0)
提交回复
热议问题