2

Webを何時間も検索しましたが、TPicture.Graphicからパレットを取得する方法について何も見つかりません。また、カラーピッカーのセルを塗りつぶすためにこれらの値をTStringListに渡すことができるように、カラー値を取得する必要があります。

これが私が現在持っているコードです:

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;

Bitmap、Jpeg、PngImage、GIfImgなどのすべてのTPicture画像タイプをサポートしたいので、Image1.Picture.Graphicに含まれている画像を使用してABitmapのキャンバスに描画しています。

どんな援助もいただければ幸いです。私は正しい道を進んでいますか、それとも何か別のものが必要ですか?

4

4 に答える 4

3

あなたが投稿したコードは実際には何もしません。アクセスする前にパレットをビットマップから読み戻すか、パレットを作成してビットマップに割り当てる必要があります。コードはどちらも行いません。

fBitmap次のコードは、フィールドとfBitmapPalEntries操作の結果を含む、多かれ少なかれあなたのものです。変更したすべての行にコメントしました。

  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;

エントリの少ないパレットのサポートは簡単です。エントリの数がわかったら、メモリを再割り当てする必要があります。

ReallocMem(Pal, SizeOf(TLogPalette) + SizeOf(TPaletteEntry) * (fBitmapPalEntries - 1));

pf4Bitパレットの作成は、ビットマップをまたはpf8Bitフォーマットで書き込みたい場合にのみ必要になります。おそらく色の数を減らす(ディザリング)ことによって、パレットエントリである16色または256色を決定する必要があります。次に、パレットのカラースロットに色の値を入力し、最後にコードからコメントアウトした2行を使用します。ビットマップのピクセル形式とパレットエントリの数が一致していることを確認する必要があります。

于 2009-08-06T21:01:50.647 に答える
1

グラフィックスアルゴリズムのすばらしいリソースは、色だけを扱う特定のセクションを含むefgのリファレンスライブラリで利用できます。具体的には、この記事(ソース付き)では、使用可能な色のカウントについて説明しており、最も役立つ可能性があります。

于 2009-08-06T20:57:53.337 に答える
0

自分のことはわかりませんが、パレット情報を表示し、Delphiで記述され、ソースを利用できるXNResourceEditorをご覧ください

于 2009-08-06T19:52:34.317 に答える
0

ありがとうございました....特にmghie。コードをbmp、png、gifファイル、およびpf1bit、pf4bit、pf8bit、pf16bit、pf24bitの画像で非常にうまく機能させることができました。私たちはまだコードをテストしていますが、これまでのところ非常にうまく機能しているようです。このコードが他の開発者にも役立つことを願っています。

var
  i: integer;
  fStringList: TStringList;
  fColor: TColor;
  fColorString: string;
  fPal: PLogPalette;
  fBitmapPalEntries: Cardinal;
begin
  if OpenPictureDialog1.Execute then
  begin
    Screen.Cursor := crHourGlass;
    try
      fPal := nil;
      try
        fStringList := TStringList.Create;
        Image1.Picture.LoadFromFile( OpenPictureDialog1.Filename );
        if Image1.Picture.Graphic.Palette <> 0 then
        begin
          GetMem( fPal, Sizeof( TLogPalette ) + Sizeof( TPaletteEntry ) * 255 );
          fPal.palversion := $300;
          fPal.palnumentries := 256;
          fBitmapPalEntries := GetPaletteEntries( Image1.Picture.Graphic.Palette, 0, 256, fPal.palPalEntry[ 0 ] );
          for i := 0 to fBitmapPalEntries - 1 do
          begin
            fColor := fPal.PalPalEntry[ i ].PeBlue shl 16
              + fPal.PalPalEntry[ i ].PeGreen shl 8
              + fPal.PalPalEntry[ i ].PeRed;
            fColorString := ColorToString( fColor );
            fStringList.Add( fColorString );
          end;
        end;
      finally; FreeMem( fPal ); end;
      if fStringList.Count = 0 then
        ShowMessage('No palette entries!')
      else
      // add the colors to the colorpicker here
      fStringList.Free;
    finally; Screen.Cursor := crDefault; end;
  end;
于 2009-08-07T03:22:48.613 に答える