任意で作成した画像の解像度を72DPIに変えて保存したいのですが、
どうやればよいのでしょうか??
サンプルなどがあればお願いします。
TJpegImage クラスには、dpi を設定するようなプロパティーがありませんね。
jpeg 画像のファイルフォーマットを
でしらべると、APP0 segment という区画にこの情報が書き込まれているようです。
自分でセーブしたファイルを TFileStream で開いて、APP0 segment の11バイト
目と13バイト目にビックエンディアンで書き込むことになるのでしょう。
原始的ですが、これしか思いつきません。
これは出力デバイスというかソフトへの指示になりますので画像そのものには
変化ありません。
う〜ん、難しいですね。
実際にはどうやればよろしいのでしょうか?
とりあえず Delphi の TJpegImage でつくった画像は、次のようにして
72dpi に設定できるようです。MS Photo Editor で確認しました。
function GetAPP0_Offset(ms:TMemoryStream):integer;
var
p1,p2:PByte;
begin
result := -1;
p1 := ms.Memory;
while (integer(p1)-integer(ms.Memory))<ms.Size do begin
if p1^ = $FF then begin
p2 := p1;
Inc(p2);
if p2^ = $E0 then begin
result := integer(p1)-integer(ms.Memory);
exit;
end;
end;
Inc(p1);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ms:TMemoryStream;
APPO_Offset:integer;
units,hidpi,lodpi:Byte;
dpi:WORD;
begin
ms := TMemoryStream.Create;
ms.LoadFromFile('C:\Any.jpg'); // 画像の読み込み
APPO_Offset := GetAPP0_Offset(ms);
if APPO_Offset = -1 then begin
ShowMessage('There is no APP0 Segment');
ms.Free;
exit;
end;
ms.Position := APPO_Offset+2+9;
units := 1; // units = 1: X and Y are dots per inch
ms.Write(units,1);
dpi := 72; // set 72 dpi
hidpi := HiByte(dpi);
lodpi := LoByte(dpi);
ms.Write(hidpi,1); // Xdensity High
ms.Write(lodpi,1); // Xdensity Low
ms.Write(hidpi,1); // Ydensity High
ms.Write(lodpi,1); // Ydensity Low
ms.Position := 0;
ms.SaveToFile('c:\Test.jpg'); // 画像の保存
ms.Free;
end;
jok様、ありがとうございます。
解像度変更はうまくいきました。
ちなみに、TJpegImageからTMemoryStreamに
直接受け渡すにはどうすればいいのでしょうか?
> ちなみに、TJpegImageからTMemoryStreamに
> 直接受け渡すにはどうすればいいのでしょうか?
TJpegImage には SaveToStream() メソッドがあります。
ほんとうにありがとうございました。
また、これからもよろしくお願いいたします。
m(__)m
ツイート | ![]() |