fpwritebmp.pp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. {*****************************************************************************}
  2. {
  3. $Id$
  4. This file is part of the Free Pascal's "Free Components Library".
  5. Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team
  6. BMP writer implementation.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. }
  13. {*****************************************************************************}
  14. {$mode objfpc}{$h+}
  15. unit FPWriteBMP;
  16. interface
  17. uses FPImage, classes, sysutils;
  18. type
  19. TFPWriterBMP = class (TFPCustomImageWriter)
  20. private
  21. FBytesPerPixel : Byte;
  22. procedure SetColorSize (AValue : Byte);
  23. protected
  24. function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual;
  25. procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override;
  26. public
  27. constructor Create; override;
  28. Property BytesPerPixel : Byte Read FBytesPerPixel Write SetColorSize;
  29. end;
  30. implementation
  31. uses BMPcomn;
  32. Function FPColorToRGB(Const Color : TFPColor) : TColorRGB;
  33. begin
  34. With Result,Color do
  35. begin
  36. R:=(Red and $FF00) shr 8;
  37. G:=(Green and $FF00) shr 8;
  38. B:=(Blue and $FF00) shr 8;
  39. end;
  40. end;
  41. Function FPColorToRGBA(Const Color : TFPColor) : TColorRGBA;
  42. begin
  43. With Result,Color do
  44. begin
  45. R:=(Red and $FF00) shr 8;
  46. G:=(Green and $FF00) shr 8;
  47. B:=(Blue and $FF00) shr 8;
  48. A:=(Alpha and $FF00) shr 8;
  49. end;
  50. end;
  51. constructor TFPWriterBMP.create;
  52. begin
  53. inherited create;
  54. FBytesPerPixel:=3;
  55. end;
  56. procedure TFPWriterBMP.SetColorSize (AValue : byte);
  57. begin
  58. if (AValue>4) then
  59. AValue:=4;
  60. if (AValue<1) then
  61. AValue:=1;
  62. FBytesPerPixel:=AValue;
  63. end;
  64. function TFPWriterBMP.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean;
  65. var
  66. BFH:TBitMapFileHeader;
  67. BFI:TBitMapInfoHeader;
  68. begin
  69. Result:=False;
  70. with BFI do
  71. begin
  72. Size:=sizeof(TBitMapInfoHeader);
  73. Width:=Img.Width;
  74. Height:=Img.Height;
  75. Planes:=1;
  76. BitCount:=BytesPerPixel SHL 3;
  77. Compression:=0;
  78. SizeImage:=Width*Height;
  79. XPelsPerMeter:=100;
  80. YPelsPerMeter:=100;
  81. ClrUsed:=0; // No palette yet.
  82. ClrImportant:=0;
  83. end;
  84. with BFH do
  85. begin
  86. bfType:=BMmagic;//'BM'
  87. bfOffset:=sizeof(TBitMapFileHeader)+sizeof(TBitMapInfoHeader);
  88. bfReserved:=0;
  89. bfSize:=bfOffset+BFI.SizeImage*BytesPerPixel;
  90. end;
  91. Stream.seek(0,soFromBeginning);
  92. Stream.Write(bfh,sizeof(TBitMapFileHeader));
  93. Stream.Write(bfi,sizeof(TBitMapInfoHeader));
  94. Result:=true;
  95. end;
  96. procedure TFPWriterBMP.InternalWrite (Stream:TStream; Img:TFPCustomImage);
  97. var
  98. Row,Col,nBpLine,WriteSize:Integer;
  99. aLine: PByte;
  100. S : Integer;
  101. begin
  102. If Not (BytesPerPixel in [3,4]) then
  103. Raise FPImageException.Create('Only 24 or 32 bit images are currently supported.');
  104. SaveHeader(Stream,Img);
  105. nBpLine:=Img.Width*BytesPerPixel;
  106. WriteSize:=(nBpLine+3) AND $FFFFFFFC; //BMP needs evry line 4Bytes aligned
  107. GetMem(aLine,(Img.Width+1)*BytesPerPixel);//3 extra byte for BMP 4Bytes alignement.
  108. Try
  109. for Row:=Img.Height-1 downto 0 do
  110. begin
  111. Case BytesPerPixel of
  112. 3 : for Col:=0 to img.Width-1 do
  113. PColorRGB(aLine)[Col]:=FPColorToRGB(img.colors[Col,Row]);
  114. 4 : for Col:=0 to img.Width-1 do
  115. PColorRGBA(aLine)[Col]:=FPColorToRGBA(img.colors[Col,Row]);
  116. end;
  117. Stream.Write(aLine[0],WriteSize);
  118. end;
  119. Finally
  120. FreeMem(aLine);
  121. end;
  122. end;
  123. initialization
  124. ImageHandlers.RegisterImageWriter ('BMP Format', 'bmp', TFPWriterBMP);
  125. end.
  126. {
  127. $Log$
  128. Revision 1.6 2004-02-20 23:52:49 michael
  129. + Added support for 32-bit writing. Standard is still 24 bit.
  130. Revision 1.5 2003/09/09 11:28:23 mazen
  131. * fixing copyright section in the file header
  132. Revision 1.4 2003/09/08 14:08:48 mazen
  133. - all common defintions are now included into bmpcomn unit
  134. - removed erronous code (causing exception)
  135. Revision 1.3 2003/09/08 10:38:56 luk
  136. - removed debug info
  137. * prevented exceptions when using non indexed images
  138. Revision 1.2 2003/09/04 22:29:43 luk
  139. * correct color conversion (prevent range check errors)
  140. Revision 1.1 2003/09/04 12:02:21 mazen
  141. + fpwritebmp.pas renamed to fpwritebmp.pp
  142. Revision 1.1 2003/09/04 08:44:32 mazen
  143. + Adds support of writing BMP files
  144. }