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