新手 问题 怎么把24位图像转换为8位灰度图像 (不是24位灰度图像)

fly_6189 2009-04-13 07:06:32
我找了好多的办法,可怎么变用photoshop看也是 24位的灰度图像 老郁闷了 以下是我的 代码 希望有牛人帮帮我 先谢谢

private void gray8_Click(object sender, EventArgs e)
{
if (curBitmap != null)
{

//curBitmap为我定义的 一个载入图片 为 form的私有成员变量
//新的我要的8位图像容器
Bitmap bit = new Bitmap(curBitmap.Width,curBitmap.Height,PixelFormat.Format8bppIndexed);
//可读写的方式锁定全部原图像
BitmapData data = curBitmap.LockBits(new Rectangle(0, 0, curBitmap.Width,curBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//得到首地址
IntPtr ptr1 = data.Scan0;
//可读写的方式锁定全部容器
BitmapData data2 = bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
//得到首地址
IntPtr ptr2 = data2.Scan0;
//计算24位图像的字节数
int bytes = curBitmap.Width * curBitmap.Height * 3;
//定义位图数组
byte[] grayValues = new byte[bytes];
//复制被锁定的图像到该数组
System.Runtime.InteropServices.Marshal.Copy(ptr1, grayValues, 0, bytes);
//同上
int byte8 = curBitmap.Width * curBitmap.Height;
byte [] gray8Values=new byte[byte8];
System.Runtime.InteropServices.Marshal.Copy(ptr2, gray8Values, 0, byte8);

for (int i = 0,n=0; i < bytes;i+=3 ,n++)
{
//灰度变换
double colorTemp = grayValues[i + 2] * 0.299 + grayValues[i + 1] * 0.589 + grayValues[i] * 0.114;
//这个是测试用的可以忽略 这是原图24位
grayValues[i + 2] = grayValues[i + 1] = grayValues[i] = (byte)colorTemp;
//将灰度值赋值给 容器 这是新图8位
gray8Values[n] = (byte)colorTemp;
}
//送回数组
System.Runtime.InteropServices.Marshal.Copy( gray8Values, 0,ptr2, byte8);
System.Runtime.InteropServices.Marshal.Copy( grayValues, 0,ptr1, bytes);
//解锁
curBitmap.UnlockBits(data);
bit.UnlockBits(data2);
//调色板
ColorPalette palette = bit.Palette;
//调色板结构体数组 填充
for (int i = 0; i != palette.Entries.Length; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);//(说实话这步为啥这麽做我也不知道)
}
bit.Palette = palette;

String path2 = System.AppDomain.CurrentDomain.BaseDirectory;
String str = path2 + "bb.jpg";
Bitmap b = bit.Clone(new Rectangle(0, 0, bit.Width, bit.Height), PixelFormat.Format8bppIndexed);
b.Save(@"E:\TEMP\bb.jpg", ImageFormat.Jpeg);// b.Save(@str, ImageFormat.Jpeg);
b.Dispose();
bit.Dispose();
Invalidate();

}
}
...全文
808 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly_6189 2009-04-19
  • 打赏
  • 举报
回复
谢谢大家 问题全部解决 收工
gomoku 2009-04-18
  • 打赏
  • 举报
回复
今天回的另一个贴,解释了Stride,可能对你的问题有帮助:
C#关于数组的内容读取问题
gomoku 2009-04-14
  • 打赏
  • 举报
回复
最大的问题:结果被存为jpg而不是bmp格式。.Net的编码器不见得能输出8bit灰度jpeg,但肯定能输出256色的bmp。
其次的问题:计算24位图像的字节数有隐患 - 没有考虑扫描线的对齐和Stride为负数等情况(比如宽度不是4的倍数将会出问题)。
其他的问题:大量没有意义的拷贝操作。



可参考下贴3楼代码:
【求助】如何输出 8位 灰度图像
fly_6189 2009-04-14
  • 打赏
  • 举报
回复
感谢 gomoku
对最大的问题是 jpg格式的图像没有8位的或很少见
我手里有张8位的jpg应该是8位的gif或是bmp文件改后缀名改的
不知道谁这么 山炮 怎么搞出这样的图给我!
当我把 储存文件变成bmp是问题解决了 保存的文件就是8位的
其次问题: 那个我现在还没明白那个 stride 这个到底有什么用 希望你可以给我讲解一下
我在这里先谢谢了!
其他问题:那个是我自学C#图像处理自己加上去看看效果的,让你见笑了!
fly_6189 2009-04-13
  • 打赏
  • 举报
回复
1楼够牛......
zgke 2009-04-13
  • 打赏
  • 举报
回复
懒人的做法 直接保存成GIF就是8位的了。。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧