TBitmapを使ってみる。その一
2009/11/22
delphi
アスキーアート
はじめてのdelphiです。
Delphi2010を使ってます。
勉強がてらに使ってみます。
今後、Delphiはwindows上での作業のヘルパーアプリ作成用にメインで使っていこうかなと考えてます。
お題はアスキーアートです。
どういうことをしたいかといいますと、入力された文字列をアスキーアート風に表示したいというわけです。
まず文字列処理がわからない。
制御文の書き方がわからない。
といろいろわからないことだらけですが、ジョジョになれていきたいところです。
いくつかわかったこと。
- VisualBaisicであったDebug.Printみたいなものが、OutputDebugStringとなるみたい。
- 制御文字を#13とかを文字列と+で連結できる。
- TBitmapを使えばグラフィック操作ができて、ファイルとかに簡単に入出力できる。
- ポインタとかフリーとかメモリを扱ってることを意識しないといけない。
- Bitmap.Monochrome=Trueではまった。Bitmap.PixelFormat := pf8bit;でよいかも。
- Delphi2010にコード整形が撞いている
- TBitmap が DDB を保持しているときは ScanLine プロパティは正しく扱えない!?
- TMemoで改行を入れたあげたい場合はCR+LFで。
- 自作関数からの戻り値はResultという暗黙の変数に入れてあげること。
参考リンク
TCanvas オブジェクト
2. TBitmap.Scanline を使う際の注意
Delphi では「改行コード」などの制御文字や英字など「アスキーコード表にある文字」を「#」を使って手軽に指定できます。
以下コード
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
TextIn: TEdit;
Button1: TButton;
TextOut: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//
function ScaneLine(Bitmap: TBitmap): String;
var
x, y: Integer;
P: PByteArray;
S: String;
begin
for y := 0 to Bitmap.Height - 1 do
begin
P := Bitmap.ScanLine[y];
for x := 0 to Bitmap.Width - 1 do
begin
if 0 = P[x] then
begin
S := S + '1';
end
else
begin
S := S + ' ';
end;
S := S + ' ';
end;
S := S + #13 + #10;
end;
Result := S;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
Bitmap.PixelFormat := pf8bit;
Bitmap.Width := 80;
Bitmap.Height := 30;
// Bitmap.Monochrome := True;
S := TextIn.Text;
OutputDebugStringW(PChar(S));
TextOut.Text := S;
Bitmap.Canvas.Font.Height := 30;
Bitmap.Canvas.TextOut(0, 0, S);
TextOut.Text := ScaneLine(Bitmap);
Bitmap.SaveToFile('c:\tmp\a.bmp');
Bitmap.Free;
end;
end.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
TextIn: TEdit;
Button1: TButton;
TextOut: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//
function ScaneLine(Bitmap: TBitmap): String;
var
x, y: Integer;
P: PByteArray;
S: String;
begin
for y := 0 to Bitmap.Height - 1 do
begin
P := Bitmap.ScanLine[y];
for x := 0 to Bitmap.Width - 1 do
begin
if 0 = P[x] then
begin
S := S + '1';
end
else
begin
S := S + ' ';
end;
S := S + ' ';
end;
S := S + #13 + #10;
end;
Result := S;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
Bitmap.PixelFormat := pf8bit;
Bitmap.Width := 80;
Bitmap.Height := 30;
// Bitmap.Monochrome := True;
S := TextIn.Text;
OutputDebugStringW(PChar(S));
TextOut.Text := S;
Bitmap.Canvas.Font.Height := 30;
Bitmap.Canvas.TextOut(0, 0, S);
TextOut.Text := ScaneLine(Bitmap);
Bitmap.SaveToFile('c:\tmp\a.bmp');
Bitmap.Free;
end;
end.
: