C# 如何将48bpp图像的原始数据加载到位图中?

C# 如何将48bpp图像的原始数据加载到位图中?,c#,.net,image,C#,.net,Image,我问了一个关于24bpp图像的类似问题,但我正在使用这里描述的技术,还有第二个问题,这次是关于48bpp 我有一个字节[]包含一个16位彩色深度图像。因此,从图像的左上角到右下角,依次有两个字节表示红色,两个字节表示绿色,两个字节表示蓝色。我正在将其加载到位图中,就像这样(考虑到步幅等): 如果我需要使用WPF库,这对我来说很好 更新2 因此,正如我在评论中所建议的,我想出了一些代码来生成一个字节数组,我可以对此进行推理 因此,我所做的就是输出一个长度为196*200*6的字节数组,这样我就可

我问了一个关于24bpp图像的类似问题,但我正在使用这里描述的技术,还有第二个问题,这次是关于48bpp

我有一个
字节[]
包含一个16位彩色深度图像。因此,从图像的左上角到右下角,依次有两个字节表示红色,两个字节表示绿色,两个字节表示蓝色。我正在将其加载到
位图中,就像这样(考虑到步幅等):

如果我需要使用WPF库,这对我来说很好


更新2

因此,正如我在评论中所建议的,我想出了一些代码来生成一个字节数组,我可以对此进行推理

因此,我所做的就是输出一个长度为196*200*6的字节数组,这样我就可以得到一个196像素宽200像素高的图像,每个像素6个字节(这个大小很方便,因为它足够大,可以看到,并且不意味着我需要处理步幅)。然后我决定将图片分成4个垂直条纹,每个条纹的字节为:

  • 0x00,0x00,0x00,0x00,0xFF,0xFF
  • 0x00,0x00,0x00,0x00,0x00,0x00,0xFF
  • 0x00,0x00,0x00,0x00,0xFF,0x00
  • 0x00,0x00,0x00,0x00,0x00,0x00,0x00
这意味着我可以看到颜色之间的差异,对吗?我得到的是这个,我做错了什么

以下是生成上述图像的代码:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace ImagePlayingApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            const int width = 196;
            const int height = 200;
            const int columnWidth = width / 4;
            const int bytesPerPixel = 6;

            var data = new byte[width * height * bytesPerPixel];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width * bytesPerPixel; x += bytesPerPixel)
                {
                    int i = y * width * bytesPerPixel + x;

                    // Blue and Green components
                    // always 0x00 since we are just
                    // interested in red
                    data[i] = 0x00;
                    data[i + 1] = 0x00;
                    data[i + 2] = 0x00;
                    data[i + 3] = 0x00;

                    if (x < columnWidth * bytesPerPixel)
                    { 
                        // Left most column, full red
                        data[i + 4] = 0xFF;
                        data[i + 5] = 0xFF;
                    }
                    else if (x < columnWidth * bytesPerPixel * 2)
                    {
                        // Next left, half red
                        data[i + 4] = 0x00;
                        data[i + 5] = 0xFF;
                    }
                    else if (x < columnWidth * bytesPerPixel * 3)
                    {
                        // Next left, other half red
                        data[i + 4] = 0xFF;
                        data[i + 5] = 0x00;
                    }
                    else
                    {
                        // Final column, no red
                        data[i + 4] = 0x00;
                        data[i + 5] = 0x00;
                    }
                }
            }

            using (var b = new Bitmap(width, 
                                      height, 
                                      PixelFormat.Format48bppRgb))
            {
                var bmpData = b.LockBits(
                    new Rectangle(0, 0, b.Width, b.Height), 
                    ImageLockMode.ReadWrite, 
                    b.PixelFormat);
                Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
                b.UnlockBits(bmpData);

                b.Save(@"c:\users\public\stripes2.tiff", ImageFormat.Tiff);
            }
        }
    }
}
使用系统;
使用系统图;
使用系统、绘图、成像;
使用System.IO;
使用System.Runtime.InteropServices;
命名空间ImagePlayingApplication
{
班级计划
{
静态void Main(字符串[]参数)
{
常数整数宽度=196;
const int height=200;
const int columnWidth=宽度/4;
const int bytesperpoixel=6;
var data=新字节[宽度*高度*字节/像素];
对于(int y=0;y

那么,有人知道如何将这里描述的字节数组转换成正确的位图吗?正如我所说,如果WPF中有任何东西可以帮助您,那就好了,或者我需要将其转换为64bppargb格式,我不知道什么?

所以我已经找到了方法,但它并不完美

如果我添加对
System.Xaml
PresentationCore
WindowsBase
的引用,并使用WPF图像类作为中间步骤,我可以得到一个,就像这样(使用问题中链接的文件和
ReadRawData
方法):


我想我将在我的项目中做的是ditch
Windows。完全考虑到这个问题以及RGB实际上是BGR(基本上我已经厌倦了)这一事实,绘制

你能发布一个完整的程序/示例,包括图像数据,无论是作为文件(链接)还是作为在C#中声明的字节数组吗?如果他们能够复制您的示例代码并在VisualStudio或LINQPad或类似程序中运行,这将对潜在的帮助者有所帮助。可能是Big-Endian/Little-Endian问题?尝试反转r1/r2和b1/b2。我认为48个bpp映像不直接受支持。看,我建议你创建一个只有10个左右像素的已知颜色的小图像。例如,黑色、白色、红色、绿色、蓝色、50%灰色、50%红色、50%绿色、50%蓝色。然后您将确切地知道每个像素应该是什么样子,这将有助于您的调试。似乎提供了一些可能相关的见解。另外,请参见上的备注部分。
private static byte[] ReadRawData()
{
    byte[] data;
    using (var ms = new MemoryStream())
    {
        using (var f = File.OpenRead("c:\\data16.bin"))
        {
            byte[] buffer = new byte[2048];
            int read;
            while ((read = f.Read(buffer, 0, buffer.Length)) > 0)
            {
                   ms.Write(buffer, 0, read);
            }
        }
        data = ms.ToArray();
    }
    return data;
}
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace ImagePlayingApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            const int width = 196;
            const int height = 200;
            const int columnWidth = width / 4;
            const int bytesPerPixel = 6;

            var data = new byte[width * height * bytesPerPixel];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width * bytesPerPixel; x += bytesPerPixel)
                {
                    int i = y * width * bytesPerPixel + x;

                    // Blue and Green components
                    // always 0x00 since we are just
                    // interested in red
                    data[i] = 0x00;
                    data[i + 1] = 0x00;
                    data[i + 2] = 0x00;
                    data[i + 3] = 0x00;

                    if (x < columnWidth * bytesPerPixel)
                    { 
                        // Left most column, full red
                        data[i + 4] = 0xFF;
                        data[i + 5] = 0xFF;
                    }
                    else if (x < columnWidth * bytesPerPixel * 2)
                    {
                        // Next left, half red
                        data[i + 4] = 0x00;
                        data[i + 5] = 0xFF;
                    }
                    else if (x < columnWidth * bytesPerPixel * 3)
                    {
                        // Next left, other half red
                        data[i + 4] = 0xFF;
                        data[i + 5] = 0x00;
                    }
                    else
                    {
                        // Final column, no red
                        data[i + 4] = 0x00;
                        data[i + 5] = 0x00;
                    }
                }
            }

            using (var b = new Bitmap(width, 
                                      height, 
                                      PixelFormat.Format48bppRgb))
            {
                var bmpData = b.LockBits(
                    new Rectangle(0, 0, b.Width, b.Height), 
                    ImageLockMode.ReadWrite, 
                    b.PixelFormat);
                Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
                b.UnlockBits(bmpData);

                b.Save(@"c:\users\public\stripes2.tiff", ImageFormat.Tiff);
            }
        }
    }
}
// Declare what we know
const int width = 157;
const int height = 196;
const double dpi = 50;
var format = PixelFormats.Rgb48;
int stride = (width * format.BitsPerPixel + 7) / 8;

// Get the data (see the question for this method)
var data = ReadRawData();

// Now put the data into a WiteableBitmap
var wb = new WriteableBitmap(width, height, dpi, dpi, format, null);
wb.WritePixels(new Int32Rect(0, 0, width, height), data, stride, 0);

// Encode as a TIFF
var enc = new TiffBitmapEncoder { Compression = TiffCompressOption.None };
enc.Frames.Add(BitmapFrame.Create(wb));

// And convert to a bitmap
using (var ms = new MemoryStream())
{
    enc.Save(ms);

    using (var bmp = new Bitmap(ms))
    {
        // Blergh, I feel dirty!
        bmp.Save("c:\\works.tiff", ImageFormat.Tiff);
    }
}