我问过类似的问题和24bpp图像here这样做,但我使用有描述的技术,并有第二个问题,这个时候做48bpp ...如何将48bpp图像的原始数据加载到位图中?
我有一个包含16位色彩深度的byte[]
图片。所以从图像的左上角到右下角依次有两个字节红色,两个绿色和两个蓝色。我加载此为Bitmap
像这样(考虑到跨越等):
byte[] data = ReadRawData();
// Swap from rgb to bgr
for (int i = 5; i < data.Length; i+=6)
{
var r1 = data[i - 5];
var r2 = data[i - 4];
var b1 = data[i - 1];
var b2 = data[i];
data[i - 5] = b1;
data[i - 4] = b2;
data[i - 1] = r1;
data[i] = r2;
}
// Load into a bitmap (I know the width and height, and the format
using (var b = new Bitmap(157, 196, PixelFormat.Format48bppRgb))
{
var bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
ImageLockMode.ReadWrite, b.PixelFormat);
// Here we loop through each line and make sure it is padded to
// the stride length
var bytesPerLine = b.Width * 6;
for (int i = 0; i < b.Height; i++)
{
IntPtr offset = bmpData.Scan0 + i * bmpData.Stride;
Marshal.Copy(data, i * bytesPerLine, offset, bytesPerLine);
int padding = bmpData.Stride - bytesPerLine;
if (padding > 0)
{
var pad = new byte[padding];
Marshal.Copy(pad, 0, offset + bytesPerLine, padding);
}
}
b.UnlockBits(bmpData);
// Done so save
b.Save("c:\\out.tiff", ImageFormat.Tiff);
}
它产生这一形象:
的图像是不正确的,但是,它应该是这样的:
所以,我的问题是,好了,我做了什么错?
更新
如果我换了R1,R2和B1,B2(和绿色的)中的字节序问题的情况下,但随后绘制这样的形象:
(所以仍然没有正确的 - 但是这给我们一个线索是什么也许是怎么回事?)
我已经把文件了GitHub上here这是原始数据,这样就可以保存下来,为您的磁盘,然后这个小方法打开它:
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;
}
如果我需要使用WPF库相反,这对我来说很好。
更新2
所以,在意见提出,我想出了一些代码生成的字节数组,我可以推理。因此,我所做的是输出一个长度为196 * 200 * 6的字节数组,这样我就可以得到一幅宽196像素,高200像,每像素6字节的图像(这个大小非常方便它足够大,看到一个并不意味着我不得不打扰的步幅)。然后我决定,我将分割的图片分成4个垂直条纹,其中用于每个条带的字节为:
- 0x00时,0×00,0x00时,0×00,为0xFF,0xFF的
- 0x00时,0×00,0×00,为0x00,0x00时,0xFF的
- 为0x00,0x00时,为0x00,0x00时,为0xFF,0×00
- 为0x00,0x00时,0×00,0×00,0×00,0×00
这应该意味着我可以看到颜色之间的差别对?那么,事实上,我是这样的,所以我在做什么错?:
这里是我的代码所产生的上图:
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);
}
}
}
}
因此,没有任何一个知道如何我可以将这里描述的字节数组转换成正确的位图吗?正如我所说,如果WPF中有什么可以帮助的话,那可能很好,或者我需要将它转换为,我不知道64bppargb格式或其他什么?
你可以发布一个完整的程序/例子,包括图像数据,作为文件(链接)还是用C#声明的字节数组?如果他们能够复制你的示例代码并运行在Visual Studio或LINQPad或类似的代码中,它将有助于未来的帮助者。 – 2013-03-08 19:52:11
可能是Big-Endian/Little-Endian问题?尝试反转r1/r2和b1/b2。 – 2013-03-08 20:56:21
我知道48 bpp图像不直接支持。看到http://stackoverflow.com/q/7276212/56778 – 2013-03-08 23:54:42