線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1949
推到 Plurk!
推到 Facebook!

請問如何將不是256色的圖轉成256色?

尚未結案
Naruto
一般會員


發表:20
回覆:19
積分:7
註冊:2003-03-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-08 16:26:50 IP:61.219.xxx.xxx 未訂閱
如題,比如說有一張24bit的圖,是否有辦法轉成256色, 或是算出256色的色盤? 謝謝
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-08 16:47:30 IP:61.218.xxx.xxx 未訂閱
Bmp.PixelFormat:=pf8bit;    僅供參考,歡迎繼續發言願以此功德 莊嚴佛淨土 上報四重恩 下濟三塗苦 若有見聞者 悉發菩提心 盡此一報身 同生極樂國
------
︿︿
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-08 17:55:26 IP:61.155.xxx.xxx 未訂閱
首先看一段实现24位色图像灰度化转换的代码    procedure Grayscale(const Bitmap:TBitmap); var   X: Integer;   Y: Integer;   R,G,B,Gray: Byte;   Color: TColor; begin   for Y := 0 to (Bitmap.Height - 1) do   begin     for X := 0 to (Bitmap.Width - 1) do     begin       Color := Bitmap.Canvas.Pixels[X,Y];       R := Color and $FF;       G := (Color and $FF00) shr 8;       B := (Color and $FF0000) shr 16;       Gray := Trunc(0.3 * R + 0.59 * G + 0.11 * B);       Bitmap.Canvas.Pixels[X,Y] := Gray shl 16 or Gray shl 8 or Gray;     end   end end;    {这段代码效率是非常低的,但可以方便我们理解同时一些问题}    Delphi的帮助中对TColor已经有了详细的描述,这可以方便我们理解上面的代码!     首先看:     R := Color and $FF; G := (Color and $FF00) shr 8; B := (Color and $FF0000) shr 16;     这是段常见的从TColor中提取三原色的代码,但它是什么意思呢? 首先应该知道and是与(.)运算,0.1=0,0.0=0,1.1=1,以取绿色为例:$FF00实际上就是$00FF00,它与一个TColor类型数按位进行与运算后,表示红色和绿色的位都变为了$00,而表示绿色的部分不变(0,1和1进行与运算值都不变),再右移8位,自然就获得了绿色值的8位表示!     再获得三原色的值后,就是计算灰度值,0.3 * Red + 0.59 * Green + 0.11 * Blue 这是求加权平均值的公式。(因为人眼对颜色的敏感度不同,所以权值不同,就像在pf16bit中用了6位表示绿色,其它两种颜色只用了5位,这问题以后另写文章说明)     然后就是像素颜色信息的写回,刚才是右移,现在自然就是左移,而或(+)运算就是(0+1=1,0+0=0,1+1=1),举个简单例子就是:($FF shl 16 = $FF0000) or ($FF shl 8 = $FF00) or $FF = $FFFFFF ,其实这里的或运算当然也可以用 + 代替。     虽然上面的代码实现了24位色图像的灰度化,但当图像比较大时,速度非常慢,为什么?查看相关VCL代码可知调用Bitmap.Canvas.Pixels获取,写入像素的颜色信息实际上是利用了API GetPixel、SetPixel,这种方法是非常低效的!(唯一的好处是在进行一些和颜色无关的操作,如图像的旋转,翻转时不需要因为PixelFormat的不同而修改代码)所以应该换一种更高效的访问像素点数据的方法,如用API GetDIBits、SetDIBits,但这种方法比较复杂,好在Delphi3以后版本的TBitmap中提供了Scanline。利用Scanline可以快速对像素进行访问!    还是以24位色(PixelFormats=pf24bit)为例,可改写为:    procedure Grayscale(const Bitmap:TBitmap); const   PixelCountMax = 32768; type   pRGBTripleArray = ^TRGBTripleArray;   TRGBTripleArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple; var   Row: pRGBTripleArray;   X: Integer;    Y: Integer;    Gray: Byte; begin   for Y := 0 to (Bitmap.Height - 1) do   begin     Row := Bitmap.ScanLine[Y];     for X := 0 to (Bitmap.Width - 1) do     begin       Gray := Trunc(0.3 * Row^[X].rgbtRed + 0.59 * Row^[X].rgbtGreen + 0.11 * Row^[X].rgbtBlue);       Row^[X].rgbtRed:=Gray;       Row^[X].rgbtGreen:=Gray;       Row^[X].rgbtBlue:=Gray;     end;   end; end;    上面的例子用了一个TRGBTriple数组      PRGBTriple = ^TRGBTriple;   tagRGBTRIPLE = packed record     rgbtBlue: Byte;     rgbtGreen: Byte;     rgbtRed: Byte;   end;   TRGBTriple = tagRGBTRIPLE;    这种方法会限制位图的大小,但一般不用理会,直接用TBitmap可处理不了那么大的位图    当然也可用指针的移动实现,实测结果这样更快~~~    procedure Grayscale(const Bitmap:TBitmap); var    X: Integer;    Y: Integer;    PRGB: pRGBTriple;   Gray: Byte; begin   for Y := 0 to (Bitmap.Height - 1) do   begin     PRGB := Bitmap.ScanLine[Y];     for X := 0 to (Bitmap.Width - 1) do     begin       Gray := Trunc(0.3 * PRGB^.rgbtRed + 0.59 * PRGB^.rgbtGreen + 0.11 * PRGB^.rgbtBlue);       PRGB^.rgbtRed:=Gray;       PRGB^.rgbtGreen:=Gray;       PRGB^.rgbtBlue:=Gray;       Inc(PRGB);     end;   end; end;    我相信上面的相关代码及说明对你会有一点帮助!!!    风花雪月 e梦情缘
------
风花雪月 e梦情缘
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-08 22:13:26 IP:61.70.xxx.xxx 未訂閱
哈哈  粉好  很詳細  厲害 厲害    僅供參考,歡迎繼續發言願以此功德 莊嚴佛淨土 上報四重恩 下濟三塗苦 若有見聞者 悉發菩提心 盡此一報身 同生極樂國
------
︿︿
dg822
一般會員


發表:14
回覆:38
積分:10
註冊:2004-12-16

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-12-17 17:52:52 IP:203.198.xxx.xxx 未訂閱
还是没正面回应该主题啊,,, 我也想知道~~
Lordaeron
初階會員


發表:24
回覆:93
積分:33
註冊:2004-05-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-02-09 13:54:09 IP:220.135.xxx.xxx 未訂閱
引言: 如題,比如說有一張24bit的圖,是否有辦法轉成256色, 或是算出256色的色盤? 謝謝
簡單的講, 先進行dithering, 將24bit 的色系中 找出256 個色進行近似. 最後再用256色去replace 24bit 中的近似色. 詳細的, 找影像處理(image processing) 或上網找dithering 這個字 也應可以找到一堆
junyan1014
一般會員


發表:1
回覆:2
積分:0
註冊:2005-04-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-05-04 23:08:14 IP:211.76.xxx.xxx 未訂閱
我想知道如何將RGB各除以3... 也就是3x3x3=27色... 不知道該怎麼寫呢? 困擾中...
系統時間:2024-04-19 7:21:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!