CanvasのTextOutで指定した色にするには?

解決


まさ  2010-01-06 16:39:45  No: 36763  IP: [192.*.*.*]

C++Builder5を使っています。
以前にここで文字の輪郭を描く方法をお聞きして
1ドットずつ8方向にずらして書く方法を教えていただいたのですが
この方法自体でちゃんと輪郭を書くことができたのですが
この時に最初白で1ドットずらした位置に8回かいてから
最後に赤で中央に書いているのですが、赤文字の淵の色が薄い赤になってしまいます。
ちなみに赤を書く前の白を8回書いた時も白が重ならない部分は薄い白になります。
Canvas->TestOut時に自動で補正されているのでしょうか?
(ビットマップファイルにしてペイントブラシで800%にして確認しました)
これを自動補正無しでちゃんと指定した色のみで描画する方法を教えてください。

編集 削除
font  2010-01-06 17:08:03  No: 36764  IP: [192.*.*.*]

Font.Nameは何?
フォントに拠るような気がします。

編集 削除
まさ  2010-01-06 17:11:37  No: 36765  IP: [192.*.*.*]

フォントはMS Pゴシックです。
他のフォントでも試してみたしたが結果は同じでした

編集 削除
色指定で  2010-01-06 17:34:40  No: 36766  IP: [192.*.*.*]

アルファチャンネルはどうしてる?

編集 削除
まさ  2010-01-06 17:37:19  No: 36767  IP: [192.*.*.*]

アルファチャンネルは・・・特にしていしてませんが
ちなみにCanvasはTBitmapのCanvasを使っているのですが
アルファチャンネルの指定はどこでするのですか?

編集 削除
みんみん  2010-01-06 22:39:37  No: 36768  IP: [192.*.*.*]

質問の答えではないけど、
文字の輪郭を描くならパスを使ったほうが簡単かも…

StrokePath APIとかね。

編集 削除
さらさ  2010-01-07 11:26:40  No: 36769  IP: [192.*.*.*]

アンチエイリアスじゃないの?

編集 削除
ぽむぽむ  2010-01-07 22:55:14  No: 36770  IP: [192.*.*.*]

XP(以降?)のClearTypeかな?

XPのClearTypeでフォントを滑らかに
http://trendy.nikkeibp.co.jp/article/tec/winxp/20030207/103731/

はずしていたらごめんなさい

編集 削除
通りすがり  2010-01-07 23:10:54  No: 36771  IP: [192.*.*.*]

C++Builderで構わないので、ソースを提示されてはいかがでしょうか?
何か手掛かりになるやもしれません?

編集 削除
D  2010-01-08 01:43:23  No: 36772  IP: [192.*.*.*]

「画面のプロパティ」の「デザイン」タブの[効果]ボタンで出てくる「効果」ダイアログ中の「次の方法でスクリーン フォントの縁を滑らかにする」にチェックが入っているためではないでしょうか。

そのチェックを外して下記のコードを実行してみたら「赤文字の淵の色が薄い赤になってしま」うようなことはありませんでした。


procedure TForm1.Button1Click(Sender: TObject);
var
  l_Bitmap: TBitmap;
begin
  l_Bitmap := TBitmap.Create;
  l_Bitmap.Width  := Self.ClientWidth;
  l_Bitmap.Height := Self.ClientHeight;
  with l_Bitmap.Canvas do begin
    Brush.Color := Self.Color;
    FillRect(ClientRect);
    Brush.Style := bsClear;
    Font.Assign(Self.Font);
    Font.Size  := 24;
    Font.Color := clWhite;
    TextOut(4, 4, Edit1.TEXT); //左上
    TextOut(5, 4, Edit1.TEXT); //上
    TextOut(6, 4, Edit1.TEXT); //右上
    TextOut(4, 5, Edit1.TEXT); //左
    TextOut(6, 5, Edit1.TEXT); //右
    TextOut(4, 6, Edit1.TEXT); //左下
    TextOut(5, 6, Edit1.TEXT); //下
    TextOut(6, 6, Edit1.TEXT); //右下
    Font.Color := clRed;
    TextOut(5, 5, Edit1.TEXT); //真ん中
  end;
  l_Bitmap.SaveToFile('text.bmp');
end;

編集 削除
D  2010-01-08 01:52:34  No: 36773  IP: [192.*.*.*]

いけね。l_Bitmap解放し忘れてた。


procedure TForm1.Button1Click(Sender: TObject);
var
  l_Bitmap: TBitmap;
begin
  l_Bitmap := TBitmap.Create;
  try
    l_Bitmap.Width  := Self.ClientWidth;
    l_Bitmap.Height := Self.ClientHeight;
    with l_Bitmap.Canvas do begin
      Brush.Color := Self.Color;
      FillRect(ClientRect);
      Brush.Style := bsClear;
      Font.Assign(Self.Font);
      Font.Size  := 24;
      Font.Color := clWhite;
      TextOut(4, 4, Edit1.TEXT); //左上
      TextOut(5, 4, Edit1.TEXT); //上
      TextOut(6, 4, Edit1.TEXT); //右上
      TextOut(4, 5, Edit1.TEXT); //左
      TextOut(6, 5, Edit1.TEXT); //右
      TextOut(4, 6, Edit1.TEXT); //左下
      TextOut(5, 6, Edit1.TEXT); //下
      TextOut(6, 6, Edit1.TEXT); //右下
      Font.Color := clRed;
      TextOut(5, 5, Edit1.TEXT); //真ん中
    end;
    l_Bitmap.SaveToFile('text.bmp');
  finally
    l_Bitmap.Free;
  end;
end;

編集 削除
jazzin  2010-01-08 16:50:03  No: 36774  IP: [192.*.*.*]

これは論理フォントがどのように作成されたかに関係します。
VCLのTFontでは論理フォントを作成する際、品質としてDEFAULT_QUALITYを指定しているのですが、
MSDNによれば、SystemParametersInfoAPIでSPI_GETFONTSMOOTHINGを指定して呼び出した時に、
Trueが返ってくるような場合(つまりクリアタイプが有効な場合)は自動でアンチエイリアスが有効になるようです。
ですので、自分で論理フォントを作成し、その際にNONANTIALIASED_QUALITYを指定すれば、
システムの状態に関係なくアンチエイリアスを無効にした描画が可能になると思われます。

また、一からフォント情報を指定してCreateFontやCreateFontIndirect等のAPIで作成するのは多少面倒ですので、
GetObjectを使用して現在のフォント情報を取得したあと、lfQualityだけ変更すれば楽に作成できます。
論理フォント作成についての情報はこちらのサイトが参考になるかと思います。
http://mrxray.on.coocan.jp/Halbow/Notes/N003.html

編集 削除
ウォレス  2010-01-12 15:21:41  No: 36775  IP: [192.*.*.*]

jazzinさんの解説をC++Builderコードにするとこんなかんじかな?
2007以前のバージョンだと大文字[W]は要らないかも。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TLogFontW lf ;
  GetObjectW(Label1->Font->Handle, sizeof(TLogFontW),&lf);
  lf.lfQuality  = NONANTIALIASED_QUALITY;
  Label1->Font->Handle = CreateFontIndirectW( &lf);
}

編集 削除
まさ  2010-01-12 15:44:25  No: 36776  IP: [192.*.*.*]

返事が遅くなって大変申し訳ありません。
PC自体の設定はそのままで何とかソフトで対応したいと思っていましたが
jazzinさんとウォレスさんの試してみたところ見事に補正されずにできました!
色々意見を下さって皆様ほんとうにありがとうございました。

編集 削除