Portable Bitmap PBM/PGM/PPMファイルを変換する(Delphi)
Portable Bitmap PBM/PGM/PPMファイルを読み込み、書き込む事のできるDelphiのソースコードです。クラスになっていますのでそのまま使用できます。
ソースコード
10年以上前に作成した古いコードで私すら覚えていないのですが、何かのお役に立てると嬉しいです。
//Portable Bitmap I/O Class
//
//Load 1bit(PBM) Ascii/Bainary 8bit(PGM) Ascii/Bainary 24bit(PPM) Ascii/Bainary
//Save 1bit(PBM) Ascii/Bainary 8bit(PGM) Ascii/Bainary 24bit(PPM) Ascii/Bainary
//
{$WARNINGS OFF}
unit PNMPack;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics;
type
TSaveMode=(smPBM,smPGM,smPPM);
type
TBWImage = class(TBitmap)
private
procedure BlackWhite;
protected
public
procedure Assign(Source: TPersistent); override;
procedure SaveToStream(Stream:TStream); override;
end;
type
TPNMImage = class(TBitmap)
private
FSaveMode : TSaveMode;
FBinaryMode: Boolean;
FSoftname : String;
procedure CreateGrayScalePalette(BW: Boolean);
function _GetWidth(Stream:TStream):integer;
function _GetHeight(Stream:TStream):integer;
procedure ReadPBM_Ascii(MemoryStream :TMemoryStream);
procedure ReadPGM_Ascii(MemoryStream:TMemoryStream;Size:integer);
procedure ReadPPM_Ascii(MemoryStream:TMemoryStream;Size:integer);
procedure ReadPBM_Binary(Stream :TStream;Size:integer);
procedure ReadPGM_Binary(Stream :TStream;Size:integer);
procedure ReadPPM_Binary(Stream :TStream;Size:integer);
procedure SavePBM_Ascii(Stream :TStream);
procedure SavePGM_Ascii(Stream :TStream);
procedure SavePPM_Ascii(Stream :TStream);
procedure SavePBM_Binary(Stream :TStream);
procedure SavePGM_Binary(Stream :TStream);
procedure SavePPM_Binary(Stream :TStream);
public
constructor Create;override;
procedure LoadFromStream(Stream: TStream); override;
procedure SaveToStream(Stream: TStream); override;
property SaveMode : TSaveMode read FSaveMode Write FSaveMode ;
property BinaryMode : Boolean read FBinaryMode Write FBinaryMode;
property SoftName : String read FSoftname write FSoftname;
end;
type
PRGBColor = ^TRGBColor;
TRGBColor = array[0..32768-1] of TRGBTriple;
implementation
///////////////////////////////////////////////////////////////////////////////
{--------}
{TBWImage}
{--------}
/////////
procedure TBWImage.BlackWhite;
var
X,Y,i : integer;
Colors : PRGBColor;
BufByte : Byte;
DoAutoMono : Boolean;
MonoBuffer : Double ;
Histgram : array [0..255] of integer;
Maxbyte,HistTotal,StartHistLoop,
EndHistLoop,MainCount,nBlack,nWhite,
nWidth,nHeight : integer;
begin
if Empty then Exit;
DoAutoMono :=false;
nWidth :=Width-1;
nHeight:=Height-1;
nBlack :=0;
nWhite :=0;
HistTotal := 0 ;
StartHistLoop :=0;EndHistLoop:=0;
pixelformat:=pf24bit;
FillChar(Histgram,Sizeof(Histgram),0);
for Y := 0 to nHeight do
begin
Colors:=ScanLine[Y];
for X := 0 to nwidth do
begin
BufByte:= Round((Colors[X].rgbtRed+Colors[X].rgbtGreen+Colors[X].rgbtBlue)/3 );
Histgram[Bufbyte] := Histgram[Bufbyte] +1;
end;
end;
for i := 0 to 255 do
begin
if (i<=$7F) And (Histgram[i]<>0) then inc(nBlack);
if (i>=$80) And (Histgram[i]<>0) then inc(nWhite);
end;
if (nBlack =0) or (nWhite =0) then
DoAutoMono:=True
else
begin
if nBlack<nWhite then
begin
MonoBuffer:= nWhite/ nBlack;
if MonoBuffer>2.50 then DoAutoMono:=True ;
end
else
begin
MonoBuffer:= nBlack/nWhite;
if MonoBuffer>2.50 then DoAutoMono:=True ;
end;
end;
if DoAutoMono then
begin
MainCount:=0;
Maxbyte:=0;
for i:=0 to 255 do
begin
If Histgram[i] > Maxbyte Then
begin
Maxbyte := Histgram[i] ;
MainCount := i ;
end;
end;
StartHistLoop :=MainCount;
EndHistLoop := StartHistLoop or 1 ;
While HistTotal < Round((Width) * (height) / 2) do
begin
If (StartHistLoop >= $00) And (StartHistLoop <= $FF) Then
begin
HistTotal := HistTotal + Histgram[StartHistLoop] ;
StartHistLoop := StartHistLoop - 1 ;
end;
If (EndHistLoop >= $00) And (EndHistLoop <= $FF) Then
begin
HistTotal := HistTotal + Histgram[EndHistLoop] ;
EndHistLoop := EndHistLoop + 1;
End;
end;
end;
for Y := 0 to nHeight do
begin
Colors:=ScanLine[Y];
for X := 0 to nwidth do
begin
BufByte:= Round((Colors[X].rgbtRed+Colors[X].rgbtGreen+Colors[X].rgbtBlue)/3 ) ;
if DoAutoMono then
begin
if (BufByte >= StartHistLoop) And (BufByte <= EndHistLoop) Then
begin
Colors[X].rgbtRed :=$FF;
Colors[X].rgbtGreen :=$FF;
Colors[X].rgbtBlue :=$FF;
end
else
begin
Colors[X].rgbtRed :=$00;
Colors[X].rgbtGreen :=$00;
Colors[X].rgbtBlue :=$00;
end;
end
else
begin
if BufByte>=128 then
begin
Colors[X].rgbtRed :=$FF;
Colors[X].rgbtGreen :=$FF;
Colors[X].rgbtBlue :=$FF;
end
else
begin
Colors[X].rgbtRed :=$00;
Colors[X].rgbtGreen :=$00;
Colors[X].rgbtBlue :=$00;
end;
end;
end;
end;
Monochrome :=True;
pixelformat :=pf1bit;
end;
/////////
procedure TBWImage.SaveToStream(Stream:TStream);
begin
BlackWhite;
inherited SaveToStream(Stream);
end;
/////////
procedure TBWImage.Assign(Source: TPersistent);
begin
inherited Assign(Source);
BlackWhite;
end;
{---------}
{TPNMImage}
{---------}
///////////
constructor TPNMImage.Create;
begin
inherited Create;
FBinaryMode :=True;
FSaveMode :=smPBM;
FSoftname :='Created by GraphicConvert-Library';
end;
////////
function TPNMImage._GetWidth(Stream:TStream):integer;
Var
Buf : char;
_Width : String;
begin
_Width :='';
Stream.read(Buf,1);
if Buf <> #10 then raise Exception.Create('PBM/PGM/PPMファイルではありません。');
Stream.read(Buf,1);
if Buf <>'#' then raise Exception.Create('PBM/PGM/PPMファイルではありません。');
repeat
Stream.Read(Buf,1);
until Buf= #10;
repeat
Stream.Read(Buf,1);
if Buf=' ' then Break;
_Width :=_Width+Buf;
until Buf=' ';
Result:=Strtoint(_Width);
end;
////////
function TPNMImage._GetHeight(Stream:TStream):integer;
Var
Buf : char;
_Height : String;
begin
_Height :='';
repeat
Stream.Read(Buf,1);
if Buf=#10 then Break;
_Height :=_Height+Buf;
until Buf=#10;
Stream.Position :=Stream.Position;
Result:=Strtoint(_Height);
end;
/////////
procedure TPNMImage.CreateGrayScalePalette(BW: Boolean);
var
i: Integer;
LogPalette: TMaxLogPalette;
begin
FillChar(LogPalette, SizeOf(LogPalette), 0);
LogPalette.palVersion := $300;
if BW then
begin
LogPalette.palNumEntries := 2;
LogPalette.palPalEntry[0].peBlue := 255;
LogPalette.palPalEntry[0].peGreen := 255;
LogPalette.palPalEntry[0].peRed := 255;
end
else
begin
LogPalette.palNumEntries := 256;
for i := 0 to 255 do
begin
LogPalette.palPalEntry[i].peBlue := i;
LogPalette.palPalEntry[i].peGreen := i;
LogPalette.palPalEntry[i].peRed := i;
end;
end;
Palette := CreatePalette(PLogPalette(@LogPalette)^);
end;
/////////
procedure TPNMImage.ReadPBM_Ascii(MemoryStream :TMemoryStream);
procedure AsciitoBinary(Var MemoryStream:TMemoryStream) ;
var
_Size ,i : integer;
Buffer : Pointer;
Line : Pbyte;
Pixel_1,Pixel_0 : Byte;
begin
_Size :=MemoryStream.size;
GetMem(Buffer,_Size);
Line :=PByte(Buffer) ;
Move(MemoryStream.Memory^,Line^,_Size);
MemoryStream.size :=0; MemoryStream.Position:=0;
Pixel_1 :=1; Pixel_0:=0;
for i :=1 to _Size do
begin
case Line^ of
$30 :MemoryStream.Write(Pixel_0,1);
$31 :MemoryStream.Write(Pixel_1,1);
end ;
inc(Line);
end;
FreeMem(Buffer);
MemoryStream.size :=MemoryStream.size;
end;
Var
BufByte : Byte;
Line8 : PByte;
X,Y : integer;
_Mod,_Width,_Height :integer;
Buffer : Pointer;
Line : PByte;
begin
_Mod:= (Width mod 8);
_Width :=Width;
_Height :=Height-1;
AsciitoBinary(MemoryStream);
MemoryStream.position:=0;
GetMem(Buffer,MemoryStream.size);
Line :=PByte(Buffer);
Move(MemoryStream.memory^,Line^,MemoryStream.Size);
try
for Y := 0 to _Height do
begin
Line8 := ScanLine[Y];
BufByte := 0;
for X := 1 to _Width do
begin
BufByte := (BufByte shl 1) or (Line^ and 1);
inc(Line);
if (X mod 8) = 0 then
begin
Line8^ := BufByte;
Inc(Line8);BufByte := 0;
end;
end;
if _Mod <> 0 then Line8^ := BufByte shl (8 - (Width mod 8));
end;
except
FreeMem(Buffer);
raise Exception.Create('イメージデータが不正です。');
end;
FreeMem(Buffer);
end;
/////////
procedure TPNMImage.ReadPGM_Ascii(MemoryStream:TMemoryStream;Size:integer);
var
_Size ,i : integer;
Buffer,Buffer2 : Pointer;
Line8,Lines : PByte;
Line : PByte;
Y,Count : integer;
nWidth,nHeight : integer;
BufByte : array[0..2] of Byte ;
begin
Count :=0;
nWidth :=Width; nHeight :=Height-1;
FillChar(BufByte,3,0);
_Size :=Size;
GetMem(Buffer,_Size);
Line :=PByte(Buffer) ;
GetMem(Buffer2,_Size);
Line8 :=PByte(Buffer2) ;
Move(MemoryStream.Memory^,Line^,_Size);
try
for i :=1 to _Size do
begin
if Line^ in [$30,$31,$32,$33,$34,$35,$36,$37,$38,$39] then
begin
case Count of
0 : BufByte[0]:=Line^-$30;
1 : BufByte[1]:=Line^-$30;
2 : BufByte[2]:=Line^-$30;
end;
inc(Count);
end
else
begin
if Count<>0 then
begin
Case Count of
1 : Line8^:= BufByte[0] ;
2 : Line8^:= BufByte[0]*10+BufByte[1] ;
3 : Line8^:= BufByte[0]*100+BufByte[1]*10+BufByte[2] ;
end;
Inc(Line8);
Count:=0;
FillChar(BufByte,3,0);
end;
end;
inc(Line);
end;
if Count<>0 then
begin
Case Count of
1 : Line8^:= BufByte[0] ;
2 : Line8^:= BufByte[0]*10+BufByte[1] ;
3 : Line8^:= BufByte[0]*100+BufByte[1]*10+BufByte[2] ;
end;
end;
except
FreeMem(Buffer);
FreeMem(Buffer2);
raise Exception.Create('イメージデータが不正です。');
end;
FreeMem(Buffer);
try
Dec(Line8,(Width*Height)-1);
for Y := 0 to nHeight do
begin
Lines := ScanLine[Y];
Move(Line8^,Lines^,nWidth);
inc(Line8,nWidth);
end;
except
FreeMem(Buffer2);
raise Exception.Create('イメージデータが不正です。');
end;
FreeMem(Buffer2);
end;
/////////
procedure TPNMImage.ReadPPM_Ascii(MemoryStream:TMemoryStream;Size:integer);
var
_Size ,i : integer;
Buffer,Buffer2 : Pointer;
Line,Line8 : PByte;
X,Y,Count : integer;
nWidth,nHeight : integer;
BufByte : array[0..2] of Byte ;
Line24 : PRGBColor;
begin
Count :=0;
nWidth :=Width-1; nHeight :=Height-1;
FillChar(BufByte,3,0);
_Size :=Size;
GetMem(Buffer,_Size);
Line :=PByte(Buffer) ;
GetMem(Buffer2,Width*Height*3);
Line8 :=PByte(Buffer2) ;
Move(MemoryStream.Memory^,Line^,_Size);
try
for i :=1 to _Size do
begin
if Line^ in [$30,$31,$32,$33,$34,$35,$36,$37,$38,$39] then
begin
case Count of
0 : BufByte[0]:=Line^-$30;
1 : BufByte[1]:=Line^-$30;
2 : BufByte[2]:=Line^-$30;
end;
inc(Count);
end
else
begin
if Count<>0 then
begin
Case Count of
1 : Line8^:= BufByte[0] ;
2 : Line8^:= BufByte[0]*10+BufByte[1] ;
3 : Line8^:= BufByte[0]*100+BufByte[1]*10+BufByte[2] ;
end;
inc(Line8);
Count:=0;
FillChar(BufByte,3,0);
end;
end;
inc(Line);
end;
if Count<>0 then
begin
Case Count of
1 : Line8^:= BufByte[0] ;
2 : Line8^:= BufByte[0]*10+BufByte[1] ;
3 : Line8^:= BufByte[0]*100+BufByte[1]*10+BufByte[2] ;
end;
end;
except
FreeMem(Buffer);
FreeMem(Buffer2);
raise Exception.Create('イメージデータが不正です。');
end;
FreeMem(Buffer);
MemoryStream.Position:=0;
Dec(Line8,(Width*Height*3)-1);
try
for Y := 0 to nHeight do
begin
Line24 := ScanLine[Y];
for X := 0 to nWidth do
begin
Line24[X].rgbtred :=Line8^;
inc(Line8);
Line24[X].rgbtgreen :=Line8^;
inc(Line8);
Line24[X].rgbtblue:=Line8^;
inc(Line8);
end;
end ;
except
FreeMem(Buffer2);
raise Exception.Create('イメージデータが不正です。');
end;
FreeMem(Buffer2);
end;
/////////
procedure TPNMImage.ReadPBM_Binary(Stream :TStream;Size:integer);
Var
Y,X :integer;
Buffer :Pointer;
Line8,Line : Pbyte;
MemoryStream :TMemoryStream;
nWidth,nHeight,_mod :integer;
begin
MemoryStream :=TMemoryStream.Create;
MemoryStream.CopyFrom(Stream,size);
MemoryStream.Position :=0;
GetMem(Buffer,Size);
Line :=Pbyte(Buffer);
Move(MemoryStream.Memory^,Line^,size);
MemoryStream.Free;
nWidth := (Width div 8)-1;
nHeight:= Height-1;
_mod := (Width mod 8);
try
for Y := 0 to nHeight do
begin
Line8 := ScanLine[Y];
for X := 0 to nWidth do
begin
Line8^ := Line^;
Inc(Line8);
inc(Line);
end;
if _mod <> 0 then
begin
Line8^ := Line^;
inc(Line);
end;
end ;
except
Freemem(Buffer);
raise Exception.Create('イメージデータが不正です。');
end;
Freemem(Buffer);
end;
/////////
procedure TPNMImage.ReadPGM_Binary(Stream :TStream;Size:integer);
Var
Y :integer;
Buffer :Pointer;
Line8,Line : Pbyte;
MemoryStream :TMemoryStream;
nWidth,nHeight : integer;
begin
MemoryStream :=TMemoryStream.Create;
MemoryStream.CopyFrom(Stream,size);
MemoryStream.Position :=0;
GetMem(Buffer,Size);
Line :=Pbyte(Buffer);
Move(MemoryStream.Memory^,Line^,size);
MemoryStream.Free;
nWidth :=Width;
nHeight :=Height-1;
try
for Y := 0 to nHeight do
begin
Line8 := ScanLine[Y];
Move(Line^,Line8^,nWidth);
inc(Line,nWidth);
end;
except
Freemem(Buffer);
raise Exception.Create('イメージデータが不正です。');
end;
Freemem(Buffer);
end;
/////////
procedure TPNMImage.ReadPPM_Binary(Stream :TStream;Size:integer);
Var
Y,X :integer;
Line24 : PRGBColor;
Line8 : pbyte;
MemoryStream :TMemoryStream;
Buffer :Pointer;
nWidth,nHeight :integer;
begin
MemoryStream :=TMemoryStream.Create;
MemoryStream.CopyFrom(Stream,size);
MemoryStream.Position :=0;
GetMem(Buffer,Size);
Line8 :=Pbyte(Buffer);
Move(MemoryStream.Memory^,Line8^,size);
MemoryStream.Free;
nWidth :=Width-1;
nHeight :=Height-1;
try
for Y := 0 to nHeight do
begin
Line24 := ScanLine[Y];
for X := 0 to nWidth do
begin
Line24[X].rgbtred :=Line8^;
inc(Line8);
Line24[X].rgbtGreen :=Line8^;
inc(Line8);
Line24[X].rgbtBlue :=Line8^;
inc(Line8);
end;
end ;
except
Freemem(Buffer);
raise Exception.Create('イメージデータが不正です。');
end;
Freemem(Buffer);
end;
/////////
procedure TPNMImage.SavePBM_Ascii(Stream :TStream);
Var
X,Y : integer;
Lines : pRGBColor;
StringStream : TStringStream;
Count : integer;
Buf : String;
BMP : TBitmap;
BW : TBWImage;
_Width,_Height :integer;
begin
BMP :=TBitmap.Create;
BMP.Assign(Self);
if BMP.PixelFormat<>pf1bit then
begin
BW :=TBWImage.Create;
BW.Assign(BMP);
BMP.Assign(BW);
BW.Free;
end;
BMP.PixelFormat :=pf24bit;
Count := 0; _Width :=Width-1; _Height :=Height-1;
StringStream := TStringStream(Stream);
buf :='P1'#10+'# '+Softname+#10 + inttostr(Width)+' '+inttostr(Height)+#10;
try
for Y := 0 to _Height do
begin
Lines:=BMP.ScanLine[Y];
for X := 0 to _Width do
begin
inc(Count);
if (Lines[X].rgbtRed<=128 ) And (Lines[X].rgbtGreen<=128 ) And (Lines[X].rgbtBlue<=128 ) then
begin
if Count<35 then
buf:=buf+'1 '
else
begin
buf:=buf+'1'#10;
Count:=0;
end;
end
else
begin
if Count<35 then
buf:=buf+'0 '
else
begin
buf:=buf+'0'#10;
COunt:=0;
end;
end;
end;
end;
StringStream.WriteString(buf);
BMP.Free;
except
end;
end;
/////////
procedure TPNMImage.SavePBM_Binary(Stream :TStream);
Var
X,Y : integer;
Lines : PByte;
StringStream : TStringStream;
Buf : String;
BMP : TBitmap;
BW : TBWImage;
Buffer : Pointer;
Line8 : PByte;
_DecCount : integer;
_Mod,_Height,_Width :integer;
begin
BMP :=TBitmap.Create;
BMP.Assign(Self);
if BMP.PixelFormat<>pf1bit then
begin
BW :=TBWImage.Create;
BW.Assign(BMP);
BMP.Assign(BW);
BW.Free;
end;
_Mod:=(BMP.Width mod 8);
_Width :=(BMP.Width div 8) -1;
_Height :=BMP.Height-1;
_DecCount :=0;
StringStream := TStringStream(Stream);
Buf :='P4'+#10+'# '+Softname+#10 +inttostr(Width)+' '+inttostr(Height)+#10;
StringStream.WriteString(Buf);
Stream :=TStream(StringStream);
GetMem(Buffer,Round((Width*Height)/8)+1);
Line8:=PByte(Buffer);
try
for Y := 0 to _Height do
begin
Lines := BMP.ScanLine[Y];
for X := 0 to _Width do
begin
Line8^:= not Lines^ ;
Inc(Lines); inc(Line8); inc(_DecCount);
end;
if _Mod <> 0 then
begin
Line8^:=not Lines^ ;
inc(Line8); inc(_DecCount);
end;
end;
Dec(Line8, _DecCount);
Stream.Write(Line8^,_DecCount);
finally
BMP.Free;
FreeMEm(Buffer);
end;
end;
/////////
procedure TPNMImage.SavePGM_Ascii(Stream :TStream);
Var
X,Y : integer;
Lines8 : Byte;
Lines : pRGBColor;
StringStream : TStringStream;
Buf : string;
BMP : TBItmap;
Count ,bufcount : integer;
_Pos : integer;
nWidth,nHeight :integer;
begin
BMP :=TBitmap.Create;
BMP.Assign(Self);
BMP.PixelFormat := pf24bit;
StringStream := TStringStream(Stream);
nWidth :=BMP.Width-1;
nHeight :=BMP.Height-1;
buf :='P2'#10+'# '+Softname+#10 +inttostr(Width)+' '+inttostr(Height)+#10+'255' +#10 ;
StringStream.Writestring(Buf);
_Pos :=Length(Buf) ;
buf :='';
Bufcount :=_Pos;
Count :=1;
try
for Y := 0 to nHeight do
begin
Lines:=BMP.ScanLine[Y];
for X := 0 to nWidth do
begin
if _Pos <>bufcount then buf :=buf+' ' ;
if bufcount>_Pos+(67*Count) then
begin
buf:=buf+#10;
inc(Count);
end;
Lines8 :=Round((Lines[X].rgbtred +Lines[X].rgbtBlue+Lines[X].rgbtGreen) /3) ;
Buf :=buf+inttostr(Lines8);
bufcount :=bufCount+sizeof(buf);
end;
StringStream.Writestring(buf);
buf:='';
end;
finally
BMP.FRee;
end;
end;
/////////
procedure TPNMImage.SavePGM_Binary(Stream :TStream);
Var
X,Y : integer;
Lines8 : Byte;
Lines : pRGBColor;
StringStream : TStringStream;
Buf : string;
BMP : TBItmap;
bufStream : TMemoryStream ;
nWidth,nHeight : integer;
begin
bufStream :=TMemoryStream .Create;
bufStream.Position :=0;
BMP :=TBitmap.Create;
BMP.Assign(Self);
nWidth :=BMP.Width-1;
nHeight :=BMP.Height-1;
BMP.PixelFormat := pf24bit;
StringStream := TStringStream(Stream);
buf :='P5'#10+'# '+Softname+#10 +inttostr(Width)+' '+inttostr(Height)+#10+'255' +#10 ;
StringStream.WriteString(buf);
buf:='';
Stream :=TStream(StringStream);
try
for Y := 0 to nHeight do
begin
Lines:=BMP.ScanLine[Y];
for X := 0 to nWidth do
begin
Lines8 :=Round((Lines[X].rgbtred +Lines[X].rgbtBlue+Lines[X].rgbtGreen) /3) ;
bufStream.Write(Lines8,1);
end;
end;
Stream.CopyFrom(BufStream,0);
finally
BMP.FRee;
bufStream.Free;
end;
end;
//PPM のASCIIコード保存
procedure TPNMImage.SavePPM_Ascii(Stream :TStream);
Var
X,Y : integer;
Lines8 : Byte;
Lines : pRGBColor;
StringStream : TStringStream;
Buf : String;
BMP : TBItmap;
Count,bufcount : integer;
Pos : integer;
nWidth,nHeight : integer;
begin
BMP :=TBitmap.Create;
BMP.Assign(Self);
BMP.PixelFormat := pf24bit;
StringStream := TStringStream(Stream);
nWidth :=BMP.Width-1;
nHeight :=BMP.Height-1;
buf :='P3'#10+'# '+Softname+#10 +inttostr(Width)+' '+inttostr(Height)+#10+'255' +#10 ;
StringStream.Writestring(buf);
Pos :=length(buf) ;
buf :='';
bufcount :=pos;
Count :=1;
try
for Y := 0 to nHeight do
begin
Lines:=BMP.ScanLine[Y];
for X := 0 to nWidth do
begin
if Pos <>bufcount then buf :=buf+' ' ;
if bufcount>Pos+(23*Count) then
begin
buf :=buf+#10;
inc(Count);
end;
Lines8 :=Lines[X].rgbtRed ;
Buf :=buf+inttostr(Lines8);
Buf :=Buf+' ';
Lines8 :=Lines[X].rgbtGreen ;
Buf :=buf+inttostr(Lines8);
Buf :=Buf+' ';
Lines8 :=Lines[X].rgbtBlue ;
Buf :=buf+inttostr(Lines8);
bufcount :=bufCount+sizeof(buf);
end;
StringStream.Writestring(buf);
buf:='';
end;
BMP.FRee;
except
end;
end;
/////////
procedure TPNMImage.SavePPM_Binary(Stream :TStream);
Var
X,Y : integer;
Lines : pRGBColor;
StringStream : TStringStream;
Buf : String;
BMP : TBItmap;
bufStream : TMemoryStream ;
begin
bufStream :=TMemoryStream .Create;
bufStream.Position :=0;
BMP :=TBitmap.Create;
BMP.Assign(Self);
BMP.PixelFormat := pf24bit;
StringStream := TStringStream(Stream);
buf :='P6'#10+'# '+Softname+#10 +inttostr(Width)+' '+inttostr(Height)+#10+'255' +#10 ;
StringStream.WriteString(buf);
buf :='';
Stream :=TMemoryStream(StringStream);
try
for Y := 0 to BMP.Height - 1 do
begin
Lines:=BMP.ScanLine[Y];
for X := 0 to Width-1 do
begin
bufStream.Write(Lines[X].rgbtred,1);
bufStream.Write(Lines[X].rgbtgreen,1);
bufStream.Write(Lines[X].rgbtBlue,1);
end;
end;
Stream.CopyFrom(BufStream,0);
finally
BMP.FRee;
bufStream.Free;
end;
end;
/////////
procedure TPNMImage.SaveToStream(Stream: TStream);
begin
if (FSaveMode =smPBM) AND (BinaryMode) then
SavePBM_Binary(Stream) ;
if (FSaveMode =smPBM) AND (not BinaryMode) then
SavePBM_Ascii(Stream) ;
if (FSaveMode =smPGM) AND (BinaryMode) then
SavePGM_Binary(Stream) ;
if (FSaveMode =smPGM) AND (not BinaryMode) then
SavePGM_Ascii(Stream) ;
if (FSaveMode =smPPM) AND (BinaryMode) then
SavePPM_Binary(Stream) ;
if (FSaveMode =smPPM) AND (not BinaryMode) then
SavePPM_Ascii(Stream) ;
end;
/////////
procedure TPNMImage.LoadFromStream(Stream: TStream);
var
Buffer : char ;
Pixel : Byte;
Count : integer;
MemoryStream : TMemoryStream ;
begin
Handle := 0; Count:=0;
Stream.Read(Buffer,1);
if Buffer <> 'P' then raise Exception.Create('このファイルはPBM/PGM/PPMフォーマットではありません。');
Stream.Read(Buffer,1);
Case Strtoint(Buffer) of
//PBM Ascii
1:
begin
PixelFormat := pf1Bit;
Width := _GetWidth(Stream);
Height := _GetHeight(Stream);
if (Width <=0) or (Height <=0) then raise Exception.Create('イメージのサイズが不正です。');
CreateGrayScalePalette(True);
MemoryStream :=TMemoryStream.Create;
MemoryStream.CopyFrom(Stream,Stream.size-Stream.position);
MemoryStream.Position:=0;
ReadPBM_Ascii(MemoryStream);
MemoryStream.Free;
end;
//PGM Ascii
2: begin
PixelFormat := pf8Bit;
Width := _GetWidth(Stream);
Height := _GetHeight(Stream);
if (Width <=0) or (Height <=0) then raise Exception.Create('イメージのサイズが不正です。');
CreateGrayScalePalette(False);
repeat
Stream.Read(Pixel,1);
if Pixel =$0A then Break;
inc(Count);
if Count=100 then raise Exception.Create('このファイルは読込めません。');
Until Pixel=-1;
MemoryStream :=TMemoryStream.Create;
MemoryStream.CopyFrom(Stream,Stream.size-Stream.position);
MemoryStream.Position:=0;
ReadPGM_Ascii(MemoryStream,MemoryStream.size);
MemoryStream.Free;
end;
//PPM Ascii
3: begin
PixelFormat := pf24Bit;
Width := _GetWidth(Stream);
Height := _GetHeight(Stream);
if (Width <=0) or (Height <=0) then raise Exception.Create('イメージのサイズが不正です。');
repeat
Stream.Read(Pixel,1);
if Pixel =$0A then Break;
inc(Count);
if Count=100 then raise Exception.Create('このファイルは読込めません。');
Until Pixel=-1;
MemoryStream :=TMemoryStream.Create;
MemoryStream.CopyFrom(Stream,Stream.size-Stream.position);
MemoryStream.Position:=0;
ReadPPM_Ascii(MemoryStream,MemoryStream.size);
MemoryStream.FRee;
end;
//PBM Binary
4: begin
PixelFormat := pf1Bit;
Width := _GetWidth(Stream);
Height := _GetHeight(Stream);
if (Width <=0) or (Height <=0) then raise Exception.Create('イメージのサイズが不正です。');
CreateGrayScalePalette(True);
ReadPBM_Binary(Stream,Stream.size-Stream.Position);
end;
//PGM Binary
5: begin
PixelFormat := pf8Bit;
Width := _GetWidth(Stream);
Height := _GetHeight(Stream);
if (Width <=0) or (Height <=0) then raise Exception.Create('イメージのサイズが不正です。');
CreateGrayScalePalette(false);
Count :=0;
repeat
Stream.Read(Pixel,1);
if Pixel =$0A then Break;
inc(Count);
if Count=100 then raise Exception.Create('このファイルは読込めません。');
Until Pixel=-1;
ReadPGM_Binary(Stream,Stream.Size-Stream.Position);
end;
//PPM Binary
6: begin
PixelFormat := pf24Bit;
Width := _GetWidth(Stream);
Height := _GetHeight(Stream);
if (Width <=0) or (Height <=0) then raise Exception.Create('イメージのサイズが不正です。');
Count :=0;
repeat
Stream.Read(Pixel,1);
if Pixel =$0A then Break;
inc(Count);
if Count=100 then raise Exception.Create('このファイルは読込めません。');
Until Pixel=-1;
ReadPPM_Binary(Stream,Stream.Size-Stream.Position);
end;
else
raise Exception.Create('このファイルは読込めません。');
end;
end;
initialization
TPicture.RegisterFileFormat('ppm', 'Portable Pixelmap', TPNMImage);
TPicture.RegisterFileFormat('pgm', 'Portable Graymap', TPNMImage);
TPicture.RegisterFileFormat('pbm', 'Portable Bitmap', TPNMImage);
finalization
TPicture.UnregisterGraphicClass(TPNMImage);
end.
スポンサーリンク
関連記事
公開日:2015年01月07日 最終更新日:2015年02月18日
記事NO:00086
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









