搜索
首页 电脑/网络 程序设计 其他编程语言

如何实现24位图转化成8位位图!!~~

要求要在DELPHI下实现,最好能有源码!!~~

全部回答

2006-08-28

0 0
    // 它的思想是:准备一个长度为4096的数组,代表4096种颜色。 // 对图中的每一个像素,取R,G,B的最高四位,拼成一个12位的整数, // 对应的数组元素加1。
  全部统计完后,就得到了这4096种颜色的使用频率。 // 这其中,可能有一些颜色一次也没用到,即对应的数组元素为零 // (假设不为零的数组元素共有M个)。  将这些为零的数组元素清除出去, // 使得前M个元素都不为零。
  将这M个数按从大到小的顺序排列,这样, // 前256种颜色就是用的最多的颜色,它们将作为调色板上的256种颜色。 // 对于剩下的M-256种颜色并不是简单的丢弃,而是用前256种颜色中的 // 一种来代替,代替的原则是找有最小平方误差的那个。
     // 存在的问题: 在该算法中 只取了R、G、B的最高四位, // 这样剩下的几位被舍去,会使图像亮度降低。 // 当也可以取全R、G、B的八位,那样效率太低。
   // 我们可以加上一个小于16的随机数来补偿。   unit CUnit2; interface uses Windows, Graphics; type PRGBColor = ^TRGBColor; TRGBColor = record B, G, R: Byte; end; PByte = ^Byte; LColor = Record Color ,Times : Integer; end; procedure Convert(SBitmap : TBitMap ; var DBitMap : TBitMap) ; implementation var ColorCount : array[0。
    。4096] of LColor; //为记录颜色使用频率的数组 ColorTable : array[0。。4096] of Byte; // 为记录颜色索引值的数组 //统计颜色使用频率 procedure CountColor(BitMap : TBitMap;Var ClrCount : array of LColor); var Ptr : PRGBColor; i,j : Integer; CIndex : Integer; begin for i := 0 to 4096 do // 初始化ColorCount数组 begin ClrCount[i]。
    Color := i; ClrCount[i]。Times := 0; end; with BitMap do for i := 0 to ( Height - 1 ) do begin Ptr := ScanLine[i]; for j := 0 to (Width - 1) do begin //取 R、G、B三种颜色的前4位组成12位,共4096种颜色 CIndex := (Ptr。
    R and $0F0) shl 4; CIndex := CIndex + (Ptr。G and $0F0); CIndex := CIndex + ((Ptr。
  B and $0F0) shr 4); Inc(ClrCount[CIndex]。  Times,1); //计算颜色的使用次数 Inc(Ptr); end; end; end;//procedure CountColor // 清除使用次数为 0 的颜色数据,返回值为当前图像中颜色的种类 function Delzero(Var ClrCount : array of LColor): Integer; var i,CIndex : Integer; begin CIndex := 0; for i := 0 to 4096 do begin if (ClrCount[i]。
    Times <> 0) then begin ClrCount[CIndex] := ClrCount[i]; ClrCount[i]。
  Times := 0; Inc(CIndex); end; end; Result := CIndex; end;//function Delzero // 快速排序, 将各种颜色 按使用的频率排序(Hight -- Low ) procedure Sort(var A: array of LColor; Top : Integer); procedure QuickSort(var A: array of LColor; iLo, iHi: Integer); var Lo, Hi, Mid: Integer; Temp : LColor; begin Lo := iLo; Hi := iHi; Mid := A[(Lo + Hi) div 2]。
    Times; repeat while A[Lo]。Times > Mid do Inc(Lo); while A[Hi]。Times Hi; if Hi > iLo then QuickSort(A, iLo, Hi); if Lo < iHi then QuickSort(A, Lo, iHi); end; begin QuickSort(A, Low(A), Top); end; // 构建调色表 function BuildColorTable(var ClrCount : array of LColor; var Pal :PLogPalette):HPalette; var i : Integer; begin lVersion:=$300; lNumEntries:=256; for i := 0 to 255 do begin lPalEntry[i]。
    peRed := ((ClrCount[i]。Color and $0F00) shr 4) + 7; lPalEntry[i]。peGreen := (ClrCount[i]。
  Color and $0F0) + 7; lPalEntry[i]。  peBlue := ((ClrCount[i]。Color and $00F) shl 4) + 7; lPalEntry[i]。
  peFlags := 0; end; Result := CreatePalette(Pal^); end; //根据统计的信息调整图像中的颜色, 将不常用的颜色用常用的颜色代替 procedure AdjustColor(ClrNumber : Integer; ClrCount : array of LColor); var i ,C,Error,m: Integer; CIndex : Byte; begin // for i := 0 to 4096 do ColorTable[i] := 0; for i := 0 to 255 do ColorTable[ClrCount[i]。
    Color] := i; for i := 256 to ClrNumber do begin Error := 10000; CIndex := 0; C := ClrCount[i]。
  Color; for m := 0 to 255 do if abs(ClrCount[m]。  Color - C) < Error then begin Error := abs(ClrCount[m]。
  Color - C); CIndex := m; end; ColorTable[ClrCount[i]。  Color] := CIndex; end; end;//procedure AdjustColor procedure Convert(SBitmap : TBitMap; var DBitMap: TBitMap) ; var Pal: PLogPalette; i , j , t, ColorNumber: integer; SPtr : PRGBColor; DPtr : PByte; begin if (SBitMap。
    Empty) then Exit; CountColor(SBitMap,ColorCount); //统计颜色的使用频率 ColorNumber := DelZero(ColorCount); //去处不使用的颜色 Sort(ColorCount,ColorNumber); // 将颜色按使用频率排序 AdjustColor(ColorNumber,ColorCount); With DBitMap do begin PixelFormat := pf8bit; SBitMap。
    PixelFormat := pf24bit; Width := SBitMap。Width; Height := SBitMap。Height; GetMem(pal, sizeof(TLogPalette) + sizeof(TPaletteEntry) * 255); BuildColorTable(ColorCount,Pal); Palette := BuildColorTable(ColorCount,Pal); // Set DBitMap。
    Palette FreeMem(pal); for i := 0 to ( Height - 1 ) do begin SPtr := SBitMap。
  ScanLine[i]; DPtr := ScanLine[i]; for j := 0 to (Width - 1) do begin t := (SPtr。
    R and $0F0) shl 4; t := t + (SPtr。G and $0F0); t := t + ((SPtr。B and $0F0) shr 4); DPtr^ := ColorTable[t]; Inc(SPtr); Inc(DPtr); end; end; end; end; //procedure Convert end。
     ///////////////////////////// 在主程序中调用 uses CUnit2; 。。。 procedure TForm1。Button1Click(Sender: TObject); begin if OpenDialog1。
    Execute then Image1。Picture。LoadFromFile(OpenDialog1。FileName); end; procedure TForm1。
  Button2Click(Sender: TObject); var Bmp : TBitMap; begin Bmp := TBitMap。  Create; // Bmp。
  Assign(Image1。Picture。Bitmap); Convert(Image1。Picture。Bitmap,Bmp); PaintBox1。Canvas。Draw(0,0,Bmp); Bmp。
    Free; end; 。

2006-08-28

134 0
  电脑的终端是监视器,它的原理和电视机一样,当阴极射线管发射出的电子流撞击在荧光屏上时,即可转变成可见光,在这个过程中会产生对人体有害的X射线。而且在VDT周围还会产生低频电磁场,长期受电磁波辐射污染,容易导致青光眼、失明症、白血病、乳腺癌等病症。
  据不完全统计,常用电脑的人中感到眼睛疲劳的占83%,肩酸腰痛的占63.9%,头痛和食欲不振的则占56.1%和54.4%,其他还出现自律神经失调、抑郁症、动脉硬化性精神病等等。

类似问题换一批

热点推荐

热度TOP

相关推荐
加载中...

热点搜索 换一换

电脑/网络
其他编程语言
程序设计
电脑装机
操作系统/系统故障
硬件
笔记本电脑
百度
互联网
反病毒
软件
程序设计
其他编程语言
数据库
C/C++
VB
JAVA相关
C#/.NET
VC++
汇编语言
其他编程语言
其他编程语言
举报
举报原因(必选):
取消确定举报