C++Builder5を使っています。
以前にここで文字の輪郭を描く方法をお聞きして
1ドットずつ8方向にずらして書く方法を教えていただいたのですが
この方法自体でちゃんと輪郭を書くことができたのですが
この時に最初白で1ドットずらした位置に8回かいてから
最後に赤で中央に書いているのですが、赤文字の淵の色が薄い赤になってしまいます。
ちなみに赤を書く前の白を8回書いた時も白が重ならない部分は薄い白になります。
Canvas->TestOut時に自動で補正されているのでしょうか?
(ビットマップファイルにしてペイントブラシで800%にして確認しました)
これを自動補正無しでちゃんと指定した色のみで描画する方法を教えてください。
Font.Nameは何?
フォントに拠るような気がします。
フォントはMS Pゴシックです。
他のフォントでも試してみたしたが結果は同じでした
アルファチャンネルはどうしてる?
アルファチャンネルは・・・特にしていしてませんが
ちなみにCanvasはTBitmapのCanvasを使っているのですが
アルファチャンネルの指定はどこでするのですか?
質問の答えではないけど、
文字の輪郭を描くならパスを使ったほうが簡単かも…
StrokePath APIとかね。
アンチエイリアスじゃないの?
XP(以降?)のClearTypeかな?
XPのClearTypeでフォントを滑らかに
http://trendy.nikkeibp.co.jp/article/tec/winxp/20030207/103731/
はずしていたらごめんなさい
C++Builderで構わないので、ソースを提示されてはいかがでしょうか?
何か手掛かりになるやもしれません?
「画面のプロパティ」の「デザイン」タブの[効果]ボタンで出てくる「効果」ダイアログ中の「次の方法でスクリーン フォントの縁を滑らかにする」にチェックが入っているためではないでしょうか。
そのチェックを外して下記のコードを実行してみたら「赤文字の淵の色が薄い赤になってしま」うようなことはありませんでした。
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;
いけね。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;
これは論理フォントがどのように作成されたかに関係します。
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
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);
}
返事が遅くなって大変申し訳ありません。
PC自体の設定はそのままで何とかソフトで対応したいと思っていましたが
jazzinさんとウォレスさんの試してみたところ見事に補正されずにできました!
色々意見を下さって皆様ほんとうにありがとうございました。
ツイート | ![]() |