博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Winform的Bitmap调色板的一个问题
阅读量:5154 次
发布时间:2019-06-13

本文共 1547 字,大约阅读时间需要 5 分钟。

帮人做一个遥感数字图像处理的小功能,其中的数据源是Landset图像,八位灰度。

然而Winform真的太弱了,System.Drawing下的PixelFormat(像素格式)枚举居然没有提供八位灰度模式,无奈只好用

PixelFormat.Format8bppIndexed(八位颜色索引)替代,可是问题又来了···

 

要使颜色索引模式生效,必须在Bitmap的调色板中设置每个索引到具体的颜色的映射:

for
(
int
i = 0; i < 256; i++)
{
   
//
每一个灰度映射到一种颜色
    bmp.Palette.Entries[i] =
Color
.FromArgb(i, i, i);
}

运行结果,图像呈现了一种蓝色色调,没有在灰度模式下显示。

我找到了bmp.Palette的定义,Bitmap的Palette属性可读可写,是一个ColorPalette(调色板)对象()。
那么是否能够直接对这个属性赋值呢?
似乎有难度,因为“调色板”没有一个公开的构造方法。于是谷歌了一下解决方法,有一位网友是这么做的:

Bitmap
bmpTemp =
new
Bitmap
(1, 1,
PixelFormat
.Format8bppIndexed);
ColorPalette
palette = bmpTemp.Palette;
for
(
int
i = 0; i < 256; i++)
{
   palette.Entries[i] =
Color
.FromArgb(i, i, i);
}
bmp.Palette = palette;

特别构造了一个临时的Bitmap,为的就是取他的调色板。运行后,确实有效,灰度图像正常显示。

有没有不用更容易的办法呢?有!我在后面的尝试当中,发现了另一种方法:

ColorPalette
palette = bmp.Palette;
for
(
int
i = 0; i < 256; i++)
{
   palette.Entries[i] =
Color
.FromArgb(i, i, i);
}
bmp.Palette = palette;

 

和第一段代码没有什么差别啊,只是定义一个新的变量来保存bmp.Palette。这段代码如何能够起作用呢?

但确实起作用了···

 

按照正常的思维,ColorPalette是引用类型,所以palette只是复制了bmp.Palette的引用,最后一句把自己的引用重新赋值回来应当没有用处,因此效果和第一段代码应当一样!!

既然MSDN不能解决疑惑,那只有求助于Reflector了。
在Bitmap的父类Image中,找到了Palette属性的实现:

public ColorPalette get_Palette()
{
    return this._GetColorPalette();
}
private ColorPalette _GetColorPalette()
{
    ······
    ColorPalette palette = new ColorPalette(size);
    IntPtr ptr = Marshal.AllocHGlobal(size);
    ······
   
    return palette;
}

很明显,Bitmap.Palette并没有像普通的属性一样,返回对应字段的引用,而是复制了一份新的。这就好的解释了为什么第一段代码完全没有效果。

 

当然,这样的类用起来实在不爽,不了解他的内部构造,就没有办法正常使用。能改用WPF的,还是改了吧。

 

 

 

 

转载于:https://www.cnblogs.com/Realh/archive/2011/03/27/1996667.html

你可能感兴趣的文章
自定义AlertDialog控件的使用(AndroidStudio)
查看>>
提高你css技能的css开发技巧
查看>>
PHP去除顽固空格和编码问题
查看>>
【springmvc+mybatis项目实战】杰信商贸-2.数据库配置
查看>>
2.模拟器的使用
查看>>
自定义log日志
查看>>
PHP ob_get_level嵌套输出缓冲
查看>>
ubuntu下mysql整个数据库备份与还原
查看>>
cocos2d(背景图片循环滚动)
查看>>
用sublime Text2来开发ruby on rails项目
查看>>
初识Flink广播变量broadcast
查看>>
学习重要,还是学会学习重要
查看>>
C# 窗体处理自定义消息
查看>>
TFS 无法找到新加的Windows用户
查看>>
jQuery 事件函数传参异常identifier starts immediately after numeric literal
查看>>
JavaScript常见笔试题分析
查看>>
莫队入门
查看>>
[BZOJ]1071 组队(SCOI2007)
查看>>
数据结构作业第二章题解
查看>>
mysql数据库基础
查看>>