您的位置:首页 > 编程语言 > C#

windows mobile平台中使用C#将byte数组转换为Format24bppRgb格式的图片

2010-03-08 17:17 861 查看
最近在学习一个别人写的图像处理源码,但是由于其源程序注释很少,对其中的图像处理操作的理解只能通过一步一步运行。大家都知道对图像的操作其实是对图像数组的操作,因
此经过处理后的图像往往会返回一个byte类型的二维数组,例如灰度图像经过一个skeletonfilter操作后,得到一个新的图像二维数组。但是C#不像matlab那么方便,要想看到处理后的图片效果直接imshow即可。因此需要解决如何在windows mobile下将byte数组转换为Format24bppRgb格式的图片。

查找资料,获得了如何将byte数组转换为8bppIndex格式图像。但是windows mobile下pixelformat不支持8bppIndex格式,因此对其进行改进得到如下程序,将byte数组转换为24位真彩色图片(每个像素右RGB三个分量组成,各占8位,共8*3=24位)

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;

//lulu 2010年3月8日15:43:31
namespace ConsomenCodeReader.Core
{
internal class ArrayToImageUtil
{
/// <summary>
/// 将一个字节数组转换为24位真彩色图
/// </summary>
/// <param name="imageArray">字节数组</param>
/// <param name="width">图像的宽度</param>
/// <param name="height">图像的高度</param>
/// <returns>位图对象</returns>
public static Bitmap ToGrayBitmap(byte[,] imageArray, int width, int height)
{

//将用户指定的imageArray二维数组转换为一维数组rawValues
byte[] rawValues = new byte[width * height];
int index=0;
int imgwidth = imageArray.GetLength(0);
int imgheight = imageArray.GetLength(1);
for(int i=0;i<imgheight;i++)
for (int j = 0; j <imgwidth; j++)
{
rawValues[index++] = imageArray[j,i];
}

//申请目标位图的变量,并将其内存区域锁定
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

//获得图像的参数
int stride = bmpData.Stride; //扫描线的宽度

// int offset = stride - width; 转换为8位灰度图时
int offset = stride - width*3; //显示宽度与扫描线宽度的间隙,

//与8位灰度图不同width*3很重要,因为此时一个像素占3字节
IntPtr iptr = bmpData.Scan0; //获得

bmpData的内存起始位置
int scanBytes = stride * height; //用Stride宽度,表示内存区域的大小

//下面把原始的显示大小字节数组转换为内存中的实际存放的字节数组
int posScan = 0, posReal = 0; //分别设置两个位置指针指向源数组和目标数组
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存

for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{

//转换为8位灰度图时

//pixelValues[posScan++]=rawValues[posReal++];

//}

//posScan+=offset;

//此处也与8位灰度图不同,分别对R,G,B分量赋值,R=G=B

//posScan也由posScan++变为posScan+= 3;
pixelValues[posScan] =pixelValues[posScan + 1]= pixelValues[posScan+2]=rawValues[posReal++];
posScan += 3;

}
posScan += offset; //行扫描结束,要将目标位置指针移过那段间隙

}

//// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes);
bmp.UnlockBits(bmpData); //解锁内存区域

////// ---------------------------------------------------------------------------

////下面的代码是8位灰度索引图时才需要的,是为了修改生成位图的索引表,从伪彩修改为灰度
//ColorPalette tempPalette;
//using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
//{
// tempPalette = tempBmp.Palette;
//}
//for (int i = 0; i < 256; i++)
//{
// tempPalette.Entries[i] = Color.FromArgb(i, i, i);
//}

//bmp.Palette = tempPalette;

//-----------------------------------------------------------------------------

//// 算法到此结束,返回结果

return bmp;

}

}
}

经过以上的步骤后,我们就可以使用该函数返回一个bitmap类系的对象,利用bitmap.save方法,将它保存在本机上,即可查看到经过处理后的图像效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: