1

RichEdit をビットマップにレンダリングしようとしています。背景を透明にしたい。上記のコードでそれを達成できました。問題は、ビットマップを透明に設定すると、透明色のみが透明になることです。背景色とは異なり、フォント色とも異なるエッジ上のピクセルを処理する方法はありますか。つまり、エッジのピクセルを半透明にして、滑らかなビューを作成します。

    Graphics::TBitmap *bitmap = new Graphics::TBitmap();
    bitmap->Width = RichEdit1->Width ;
    bitmap->Height = RichEdit1->Height ;


    TRect BoundingBox(0,0,RichEdit1->Width, RichEdit1->Height) ;

    // Render RichEdit to bitmap
    TFormatRange formatRange;
    int twipsPerPixel = 1440 / Screen->PixelsPerInch;

    formatRange.hdc = bitmap->Canvas->Handle;
    formatRange.hdcTarget = bitmap->Canvas->Handle;
    formatRange.chrg.cpMin = 0;
    formatRange.chrg.cpMax = -1;

    formatRange.rc.top = 2 * twipsPerPixel;
    formatRange.rc.bottom = (BoundingBox.Height() - 4) * twipsPerPixel + formatRange.rc.top;
    formatRange.rc.left = 2 * twipsPerPixel;
    formatRange.rc.right = (BoundingBox.Width() - 4) * twipsPerPixel;

    // Measure text's height.
    RichEdit1->Perform(EM_FORMATRANGE, 0, 0);
    RichEdit1->Perform(EM_FORMATRANGE, 0, (LPARAM) &formatRange);

    formatRange.rc.bottom = (BoundingBox.Height() - 4) * twipsPerPixel + formatRange.rc.top;
    formatRange.rc.left = 2 * twipsPerPixel;
    formatRange.rc.right = (BoundingBox.Width() - 4) * twipsPerPixel;

    formatRange.rcPage = formatRange.rc;


    /**
    * Draw..
    **************************************************************************/
    RichEdit1->Perform(EM_FORMATRANGE, 1, (LPARAM) &formatRange);
    RichEdit1->Perform(EM_FORMATRANGE, 0, 0);


   // Draw background
   // Use different background color to see the trasparency problem
   this->Canvas->Brush->Color = clRed ;
   this->Canvas->Rectangle(0,0,RichEdit1->Width , RichEdit1->Height );

   // Draw the transparent bitmap
   bitmap->Transparent = true ;
   bitmap->TransparentColor = RichEdit1->Color ;
   this->Canvas->Draw(0,0,bitmap);

ありがとう。

4

2 に答える 2

2

フォント スムージングは​​、アルファ チャネルを使用して部分的な透明度で機能します。したがってTransparent、 およびTransparentColorプロパティはTBitmap適用されません。

使用している C++ Builder/VCL のバージョンについては言及されていませんが、より新しいバージョンでは、一部の古いバージョンよりも部分的な透過性がより適切にサポートされています。

これを機能させるPixelFormatには、ビットマップの をに設定する必要がありますpf32bitAlphaFormatに設定する必要がある場合もありますafDefined

必要なことを実行できない場合はTBitmap、GDI コマンドに戻って適切な .xml ファイルを作成する必要がありますHBITMAP。少なくともそれをHandlea のプロパティに割り当てることができTBitmap、通常はそこからすべてが動作します。

私は C++ Builder のユーザーではありませんが、Delphi の VCL については知っています。

アップデート

Delphiでこれを試してみたところ、次のようにうまくいきました:

procedure TForm4.Button1ClickBMP(Sender: TObject);
var
  BMP: TBitmap;
  fmtRange: TFormatRange;
  intPPI, Flags: Integer;
begin
  BMP := TBitmap.Create;
  Try
    BMP.PixelFormat := pf32bit;
    BMP.SetSize(RichEdit1.Width, RichEdit1.Height);

    FillChar(fmtRange, SizeOf(fmtRange), 0);
    with fmtRange do begin
      hDC := BMP.Canvas.Handle;
      hdcTarget := hDC;
      intPPI := Screen.PixelsPerInch;
      rc := Rect(
        0,
        0,
        RichEdit1.Width*1440 div intPPI,
        RichEdit1.Height*1440 div intPPI
      );
      rcPage := rc;
      chrg.cpMin := 0;
      chrg.cpMax := -1;
    end;
    Flags := 1;
    RichEdit1.Perform(EM_FORMATRANGE, Flags, Longint(@fmtRange));
    RichEdit1.Perform(EM_FORMATRANGE, 0, 0);
    BMP.SaveToFile('c:\desktop\test.bmp');
  Finally
    FreeAndNil(BMP);
  End;
end;

出力は次のようになります。アンチエイリアシングを確認するために少し拡大しています。

ここに画像の説明を入力

もうすぐそこにいるように見えるので、これがお役に立てば幸いです。

于 2011-03-14T10:40:54.467 に答える
0

David が既に回答したように、サブピクセル アンチエイリアシングには背景色の知識が必要です。これについては、この回答で詳しく説明しています。本質的に、サブピクセル アンチエイリアシングを行う場合、3 つのカラー チャネルを異なる空間オフセットを持つものとして扱います (これが解像度の明らかな増加の原因です)。これは、異なるアルファ値が必要であることを意味しますが、もちろんアルファ チャネルは 1 つしかありません。

もちろん、透明な背景に対して通常のフルピクセル グレースケール アンチエイリアシングを行うこともできます。もしかしてこれでいいのかな?上記の質問の他の回答のいくつかは、これを達成する方法を提案しています。ANTIALIASED_QUALITY構造の(vs. CLEARTYPE_QUALITY) を見てくださいLOGFONT。(私はこれを試していません。)

于 2014-11-04T09:07:48.933 に答える