首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何访问TPicture.Graphic的调色板?

如何访问TPicture.Graphic的调色板?
EN

Stack Overflow用户
提问于 2009-08-06 18:44:30
回答 4查看 3.3K关注 0票数 2

我已经在网上搜索了几个小时,但是我没有找到任何关于如何从TPicture.Graphic获取调色板的东西。我还需要获取颜色值,以便将这些值传递给TStringList,以便在颜色选择器中填充单元格。

这是我目前拥有的代码:

代码语言:javascript
复制
procedure TFormMain.OpenImage1Click( Sender: TObject );
var
  i: integer;
  S: TStringList;
  AColor: TColor;
  AColorCount: integer;
  N: string;
  Pal: PLogPalette;
  HPal: hPalette;
begin
  if OpenPictureDialog1.Execute then
  begin
    Screen.Cursor := crHourGlass;
    try
      Pal := nil;
      try
        S := TStringList.Create;
        ABitmap.Free; // Release any existing bitmap
        ABitmap := TBitmap.Create;
        Image1.Picture.LoadFromFile( OpenPictureDialog1.Filename );
        ABitmap.Canvas.Draw( 0, 0, Image1.Picture.Graphic );
        GetMem( Pal, Sizeof( TLogPalette ) + Sizeof( TPaletteEntry ) * 255 );
        Pal.palversion := $300;
        Pal.palnumentries := 256;
        for i := 0 to 255 do
        begin
          AColor := Pal.PalPalEntry[ i ].PeRed shl 16 + Pal.PalPalEntry[ i ].PeGreen shl 8 + Pal.PalPalEntry[ i ].PeBlue;
          N := ColorToString( AColor );
          S.Add( N );
        end;
        HPal := CreatePalette( Pal^ );
        ABitmap.Palette := HPal;
        Memo1.Lines := S;
      finally; FreeMem( Pal ); end;
      S.Free;
    finally; Screen.Cursor := crDefault; end;
  end;
end;

我使用Image1.Picture.Graphic中包含的图像绘制ABitmap的画布,因为我希望支持所有TPicture图像类型,例如位图、Jpeg、PngImage和GIfImg。

任何帮助都将不胜感激。我是在正确的道路上,还是需要一些不同的东西?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-08-06 21:01:51

您发布的代码实际上什么也不做。您要么必须从位图中读回调色板,然后才能访问它,要么需要创建一个调色板并将其分配给位图-您的代码既不需要这样做。

下面的代码或多或少是您的代码,其中包含用于表示操作结果的字段fBitmapfBitmapPalEntries。我注释了我更改的所有行:

代码语言:javascript
复制
  if OpenPictureDialog1.Execute then
  begin
    Screen.Cursor := crHourGlass;
    try
      Pal := nil;
      try
        S := TStringList.Create;
        fBitmap.Free; // Release any existing bitmap
        fBitmap := TBitmap.Create;
// if you want a 256 colour bitmap with a palette you need to say so
        fBitmap.PixelFormat := pf8bit;
        Image1.Picture.LoadFromFile( OpenPictureDialog1.Filename );
        fBitmap.Canvas.Draw( 0, 0, Image1.Picture.Graphic );
// access the palette only if bitmap has indeed one
        if fBitmap.Palette <> 0 then begin
          GetMem( Pal, Sizeof( TLogPalette ) + Sizeof( TPaletteEntry ) * 255 );
          Pal.palversion := $300;
          Pal.palnumentries := 256;
// read palette data from bitmap
          fBitmapPalEntries := GetPaletteEntries(fBitmap.Palette, 0, 256,
            Pal.palPalEntry[0]);
          for i := 0 to fBitmapPalEntries - 1 do
          begin
            AColor := Pal.PalPalEntry[ i ].PeRed shl 16
                    + Pal.PalPalEntry[ i ].PeGreen shl 8
                    + Pal.PalPalEntry[ i ].PeBlue;
            N := ColorToString( AColor );
            S.Add( N );
          end;
// doesn't make sense, the palette is already there
//        HPal := CreatePalette( Pal^ );
//        fBitmap.Palette := HPal;
          Memo1.Lines := S;
        end;
      finally; FreeMem( Pal ); end;
      S.Free;
    finally; Screen.Cursor := crDefault; end;
  end;

支持具有较少条目的调色板很容易,您只需在知道有多少条目后重新分配内存,如下所示

代码语言:javascript
复制
ReallocMem(Pal, SizeOf(TLogPalette) + SizeOf(TPaletteEntry) * (fBitmapPalEntries - 1));

只有当您想要以pf4Bitpf8Bit格式编写位图时,才需要创建调色板。您需要确定属于调色板条目的16或256种颜色,可能是通过减少颜色的数量(抖动)。然后用颜色值填充调色板的颜色槽,最后使用我从代码中注释掉的两行代码。您必须确保位图的像素格式和调色板条目的数量相匹配。

票数 3
EN

Stack Overflow用户

发布于 2009-08-06 20:57:53

efg's reference library上有一个很棒的图形alogithms资源,其中包括一个专门处理颜色的部分。具体地说,this文章(带源代码)讨论了计算可用颜色的数量,这可能是最好的用法。

票数 1
EN

Stack Overflow用户

发布于 2009-08-06 19:52:34

我不知道我自己,但你可以看看XN Resource Editor,它确实显示调色板信息,是用Delphi语言编写的,有可用的源码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1240673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档