Changeset 317 for GraphicTest/BGRABitmap/bgracompressablebitmap.pas
- Timestamp:
- Feb 1, 2012, 3:02:33 PM (13 years ago)
- Location:
- GraphicTest/BGRABitmap
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/BGRABitmap
-
Property svn:ignore
set to
lib
-
Property svn:ignore
set to
-
GraphicTest/BGRABitmap/bgracompressablebitmap.pas
r210 r317 1 unit bgracompressablebitmap;1 unit BGRACompressableBitmap; 2 2 3 3 {$mode objfpc}{$H+} 4 4 5 5 interface 6 7 { This unit contains the TBGRACompressableBitmap class, which 8 can be used to temporarily compress bitmaps in memory. 9 To use it, create an instance with the bitmap you want 10 to compress. You can then free the original bitmap because 11 TBGRACompressableBitmap contains all information necessary 12 to build it again. To construct again your bitmap, call 13 the GetBitmap function. 14 15 When you have your bitmap in TBGRACompressableBitmap, 16 you can call Compress function as many times as necessary 17 until all data is compressed. It does only a part of the 18 work at each call, so you can put it in a loop or in 19 a timer. When it's done, Compress returns false to 20 notify that it did nothing, which means you can 21 stop calling Compress. 22 23 In this implementation, the memory usage grows during 24 the compression process and is lower only after it is 25 finished. So it is recommended to compress one bitmap 26 at a time. } 6 27 7 28 uses … … 16 37 FWidth,FHeight: integer; 17 38 FCaption: String; 39 FBounds: TRect; 18 40 FCompressedDataArray: array of TMemoryStream; 19 41 FUncompressedData: TMemoryStream; … … 25 47 constructor Create(Source: TBGRABitmap); 26 48 function GetBitmap: TBGRABitmap; 27 function Compress: boolean; 49 50 //call Compress as many times as necessary 51 //when it returns false, it means that 52 //the image compression is finished 53 function Compress: boolean; 54 28 55 function UsedMemory: Int64; 29 56 procedure Assign(Source: TBGRABitmap); … … 38 65 uses zstream, BGRABitmapTypes; 39 66 40 const maxPartSize = 1048576; 67 // size of each chunk treated by Compress function 68 const maxPartSize = 524288; 41 69 42 70 { TBGRACompressedBitmap } … … 63 91 end; 64 92 93 { Constructs the bitmap again, decompressing if necessary. 94 After this, the image is not compressed anymore so the 95 memoy usage grows again and the access becomes fast 96 because there is no need to decompress anymore. } 65 97 function TBGRACompressableBitmap.GetBitmap: TBGRABitmap; 98 var UsedPart: TBGRABitmap; 99 UsedNbPixels: Integer; 66 100 begin 67 101 Decompress; … … 74 108 result.Caption := FCaption; 75 109 FUncompressedData.Position := 0; 76 FUncompressedData.Read(result.Data^,result.NbPixels*Sizeof(TBGRAPixel)); 77 end; 78 110 if (FBounds.Left <> 0) or (FBounds.Top <> 0) 111 or (FBounds.Right <> FWidth) or (FBounds.Bottom <> FHeight) then 112 begin 113 UsedNbPixels := (FBounds.Right-FBounds.Left)*(FBounds.Bottom-FBounds.Top); 114 if UsedNbPixels > 0 then 115 begin 116 UsedPart := TBGRABitmap.Create(FBounds.Right-FBounds.Left,FBounds.Bottom-FBounds.Top); 117 FUncompressedData.Read(UsedPart.Data^,UsedPart.NbPixels*Sizeof(TBGRAPixel)); 118 result.PutImage(FBounds.Left,FBounds.Top,UsedPart,dmSet); 119 UsedPart.Free; 120 end; 121 end else 122 FUncompressedData.Read(result.Data^,result.NbPixels*Sizeof(TBGRAPixel)); 123 end; 124 125 { Returns the total memory used by this object for storing bitmap data } 79 126 function TBGRACompressableBitmap.UsedMemory: Int64; 80 127 var i: integer; … … 86 133 end; 87 134 135 { Do one compress step or return false } 88 136 function TBGRACompressableBitmap.Compress: boolean; 89 137 var comp: Tcompressionstream; … … 91 139 begin 92 140 if FCompressedDataArray = nil then FCompressionProgress := 0; 93 if FUncompressedData = nilthen141 if (FUncompressedData = nil) or (FUncompressedData.Size = 0) then 94 142 begin 95 143 result := false; … … 104 152 partSize := maxPartSize else 105 153 partSize := integer(FUncompressedData.Size - FCompressionProgress); 154 155 //use fast compression to avoid slowing down the application 106 156 comp := Tcompressionstream.Create(clfastest,FCompressedDataArray[high(FCompressedDataArray)]); 107 157 comp.write(partSize,sizeof(partSize)); … … 136 186 end; 137 187 188 { Free all data } 138 189 procedure TBGRACompressableBitmap.FreeData; 139 190 var i: integer; … … 148 199 end; 149 200 201 { Copy a bitmap into this object. As it is copied, you need not 202 keep a copy of the source } 150 203 procedure TBGRACompressableBitmap.Assign(Source: TBGRABitmap); 204 var 205 UsedPart: TBGRABitmap; 206 NbUsedPixels: integer; 151 207 begin 152 208 FreeData; … … 161 217 FHeight := Source.Height; 162 218 FCaption := Source.Caption; 219 FBounds := Source.GetImageBounds([cRed,cGreen,cBlue,cAlpha]); 220 NbUsedPixels := (FBounds.Right-FBounds.Left)*(FBounds.Bottom-FBounds.Top); 163 221 FUncompressedData := TMemoryStream.Create; 164 FUncompressedData.Write(Source.Data^,Source.NbPixels*Sizeof(TBGRAPixel)); 222 if NbUsedPixels = 0 then exit; 223 224 if (FBounds.Left <> 0) or (FBounds.Top <> 0) 225 or (FBounds.Right <> Source.Width) or (FBounds.Bottom <> Source.Height) then 226 begin 227 UsedPart := Source.GetPart(FBounds) as TBGRABitmap; 228 FUncompressedData.Write(UsedPart.Data^,NbUsedPixels*Sizeof(TBGRAPixel)); 229 UsedPart.Free; 230 end else 231 FUncompressedData.Write(Source.Data^,Source.NbPixels*Sizeof(TBGRAPixel)); 165 232 end; 166 233
Note:
See TracChangeset
for help on using the changeset viewer.