我的代码主要是先画一个16色彩深度的图片,然后转换为4位色彩深度的图片
在转换的时候用到内存的操作,就是这个地方出了问题,大家帮我看看那地方出错了!!!
先谢谢各位了...
16位色彩图片绘制好了,没有问题
下面是转换的代码: //设置调色板
PixelFormat pf = PixelFormat.Format4bppIndexed;
Bitmap bm = new Bitmap(1, 1, pf);
ColorPalette cp = bm.Palette;//获取调色板
cp.Entries[0] = Color.FromArgb(255, 255, 0, 0);
cp.Entries[1] = Color.FromArgb(255, 0, 255, 0);
cp.Entries[2] = Color.FromArgb(255, 0, 0, 255);
cp.Entries[3] = Color.FromArgb(0, 255, 255, 255); //将其alpha值修改为0,使背景透明 //---设置调色板 //
//先绘制16位的图片,再把该图片转化位4位的带索引颜色的图片
Bitmap image = new Bitmap(32, 32, System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
image.Palette = cp;
Bitmap image16 = DrawImage16(AntDirAng,color);//调用写好的方法绘制16位色的图片
//把绘制好的16位图片转化位4位的图片
try
{
BitmapData bd ;
BitmapData bd16 ;
int h = image.Height;
int w = image.Width;
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, h, w);
unsafe
{
bd = image.LockBits(rect, ImageLockMode.WriteOnly, pf);
bd16 = image16.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format16bppRgb555);
//用指针操作的位图数据
byte* byteimage; //记录位图数据第一个像素的地址
byte* byteimage16;
if (bd.Stride > 0)
{ byteimage = (byte*)bd.Scan0.ToPointer(); }
else
{ byteimage = (byte*)bd.Scan0.ToPointer() + bd.Stride * (h - 1); }
if (bd16.Stride > 0)
{ byteimage16 = (byte*)bd16.Scan0.ToPointer(); }
else
{ byteimage16 = (byte*)bd16.Scan0.ToPointer() + bd16.Stride * (h - 1); } uint stride = (uint)Math.Abs(bd.Stride);
//用一个嵌套循环扫描源图片,进行转化
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
//转化公式:0.3R+0.59G+0.11B,
float value = 0.11F * byteimage16[i * bd16.Stride + j * 4] + 0.59F * byteimage16[i * bd16.Stride + j * 4 + 1] + 0.3F * byteimage16[
i * bd16.Stride + j * 4 + 2];
byteimage[i * bd.Stride + j] = (byte)value;
//网上的另一种转化方法,直接读取每个像素的颜色分量
//Color pixelc;
//byte* b4pixel = byteimage + i * stride + j;
//pixelc = image16.GetPixel(i, j);
//double value = (pixelc.R * 0.299) + (pixelc.G * 0.587) + (pixelc.B * 0.114);
//*b4pixel = (byte)(value * 3 / 255 + 0.5);
}// end j-width
}// end i-height
image.UnlockBits(bd);
image16.UnlockBits(bd16);
}
//end of unsafe
return image;就是内存操作unsafe中的代码有问题,请大家帮我看看啊,
在转换的时候用到内存的操作,就是这个地方出了问题,大家帮我看看那地方出错了!!!
先谢谢各位了...
16位色彩图片绘制好了,没有问题
下面是转换的代码: //设置调色板
PixelFormat pf = PixelFormat.Format4bppIndexed;
Bitmap bm = new Bitmap(1, 1, pf);
ColorPalette cp = bm.Palette;//获取调色板
cp.Entries[0] = Color.FromArgb(255, 255, 0, 0);
cp.Entries[1] = Color.FromArgb(255, 0, 255, 0);
cp.Entries[2] = Color.FromArgb(255, 0, 0, 255);
cp.Entries[3] = Color.FromArgb(0, 255, 255, 255); //将其alpha值修改为0,使背景透明 //---设置调色板 //
//先绘制16位的图片,再把该图片转化位4位的带索引颜色的图片
Bitmap image = new Bitmap(32, 32, System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
image.Palette = cp;
Bitmap image16 = DrawImage16(AntDirAng,color);//调用写好的方法绘制16位色的图片
//把绘制好的16位图片转化位4位的图片
try
{
BitmapData bd ;
BitmapData bd16 ;
int h = image.Height;
int w = image.Width;
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, h, w);
unsafe
{
bd = image.LockBits(rect, ImageLockMode.WriteOnly, pf);
bd16 = image16.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format16bppRgb555);
//用指针操作的位图数据
byte* byteimage; //记录位图数据第一个像素的地址
byte* byteimage16;
if (bd.Stride > 0)
{ byteimage = (byte*)bd.Scan0.ToPointer(); }
else
{ byteimage = (byte*)bd.Scan0.ToPointer() + bd.Stride * (h - 1); }
if (bd16.Stride > 0)
{ byteimage16 = (byte*)bd16.Scan0.ToPointer(); }
else
{ byteimage16 = (byte*)bd16.Scan0.ToPointer() + bd16.Stride * (h - 1); } uint stride = (uint)Math.Abs(bd.Stride);
//用一个嵌套循环扫描源图片,进行转化
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
//转化公式:0.3R+0.59G+0.11B,
float value = 0.11F * byteimage16[i * bd16.Stride + j * 4] + 0.59F * byteimage16[i * bd16.Stride + j * 4 + 1] + 0.3F * byteimage16[
i * bd16.Stride + j * 4 + 2];
byteimage[i * bd.Stride + j] = (byte)value;
//网上的另一种转化方法,直接读取每个像素的颜色分量
//Color pixelc;
//byte* b4pixel = byteimage + i * stride + j;
//pixelc = image16.GetPixel(i, j);
//double value = (pixelc.R * 0.299) + (pixelc.G * 0.587) + (pixelc.B * 0.114);
//*b4pixel = (byte)(value * 3 / 255 + 0.5);
}// end j-width
}// end i-height
image.UnlockBits(bd);
image16.UnlockBits(bd16);
}
//end of unsafe
return image;就是内存操作unsafe中的代码有问题,请大家帮我看看啊,
解决方案 »
- 谁能给小弟一个几行的代码?
- 又遇到问题了......
- c#和Sql server,不支持datebase关键字
- 程序突然占用cpu100%
- C#应该如何更新用户界面对象?我想实时监控剪贴板,从而控制“粘贴”菜单的启用与禁用状态。
- C#中Form窗体背景色的设制
- ---------------各位大哥,帮帮老弟啊?一个截图片代码--------在线等-------------
- 请问在C#怎么实现像Java的BeanShell的功能?
- 一个报表文件在水晶报表环境下显示正常,可放在vs.net开发环境下运行时,出现错误!
- 有没有和VB那样的API Viwer?
- C#字符串随机排列
- Redirect方法
public static class BitmapHelper
{
[StructLayout(LayoutKind.Sequential)]
private struct PixelData
{
public byte B;
public byte G;
public byte R;
public byte A;
} public static void SetAlphaChanelValue(Bitmap image, byte value)
{
if (image == null)
throw new ArgumentNullException("image");
if (image.PixelFormat != PixelFormat.Format32bppArgb)
throw new ArgumentException("Wrong PixelFormat"); BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
PixelData* pPixel = (PixelData*)bitmapData.Scan0;
for (int i = 0; i < bitmapData.Height; i++)
{
for (int j = 0; j < bitmapData.Width; j++)
{
pPixel->A = value;
pPixel++;
}
pPixel += bitmapData.Stride - (bitmapData.Width * 4);
}
}
image.UnlockBits(bitmapData);
}
}