低空飛行しながら車輪の再発明的なことが大好きな私ですm(_ _)m
PNG-Info を取得するのは Python で数行で出来たのですが Delphi でやってみようとして行き詰まってしまいました
最初 TMemoryStream で1バイトずつ読み込んでいたのですが TPngImage が TChunk で分かれていることを(今更)知り
TChunktEXt を使いましたが日本語が入っているとアドレス違反が起きます
(pngimage.pas の中の Text が AnsiString で扱われているから?)
そこで初心に戻り ChunktEXt 領域だけを取り出し System.Move するとエラーも出ず日本語も化けることなく取り出せました
(ここまでは1バイトずつ読み込んでいた時と同じ結果でした)
しかし「é」の様なアクセント文字が化けてしまいます
参照画像→https://files.catbox.moe/v9gotm.png
「Negative prompt: 3D, CGI, render, photo, text, watermark, low-quality, signature, moiré」
その部分は本来「C3 A9」になると思うのですが自分のコードで読んでもバイナリエディタ「edbin」で読んでも「E9」です
Delphi2009 だからか?と Delphi 11 CE でも試しましたが同じでした
Pythonプログラムや巷にあるウェブのPNG-Infoサービスでは問題なく表示出来ているので私の読み込み方が間違っているとは思うのですが
何かヒントがあればお教えください
>その部分は本来「C3 A9」になると思うのですが自分のコードで読んでもバイナリエディタ「edbin」で読んでも「E9」です
UTF8 なら C3 A9 ですが E9 なので UNICODE
https://0g0.org/unicode/00E9/
var
I,J: Integer;
PNG: TPNGImage;
C: TChunk;
T: TChunktEXt;
U: UnicodeString;
begin
PNG := TPngImage.Create;
PNG.LoadFromFile('v9gotm.png');
for I:=0 to PNG.Chunks.Count - 1 do
begin
C := PNG.Chunks.Item[I];
if C is TChunkTEXT then
begin
T := TChunktEXt(C);
U := '';
for J := 1 to ByteLength(T.Text) do
begin
U := U + Chr(Byte(T.TEXT[J]));
end;
Memo1.Lines.Add(U);
end;
end;
PNG.Free;
ありがとうございます
「é」もちゃんと取得出来ました
最初にてテストしていた日本語混じりの時が UTF8 だったので決めつけていました
その日本語混じりの画像の方
参照画像:https://files.catbox.moe/cbdhu3.png
では if C is TChunkTEXT then を通らなかったので調べると
こちらの Chunk.Name は 「iTXt」で iTXt チャンクという別物なのですね
取りあえず夜も更けてきましたのでやっつけで読み込めました
var
I,J,K: Integer;
PNG: TPNGImage;
C: TChunk;
T: TChunktEXt;
U: UnicodeString;
P: Char;
PB:PByte;
U8:UTF8String;
B:TBytes;
if C.Name ='tEXt' then
begin
T := TChunktEXt(C);
U := '';
for J := 1 to ByteLength(T.Text) do
begin
U := U + Chr(Byte(T.TEXT[J]));
end;
Memo1.Lines.Add(U);
end else
if C.Name ='iTXt' then
begin
SetLength(B,C.DataSize);
PB:=C.Data;
for J := 1 to C.DataSize do
begin
if PB^<>$00 then//何故かヌル文字入ってる
begin
B[K]:= Byte(PB^);
Inc(K);
end;
Inc(PB);
end;
Memo1.Text:=TEncoding.UTF8.GetString(B);
end;
……ポインタは苦手です
ツイート | ![]() |