Changeset 35 for trunk/Packages/FastGraphics/UGGraphics.pas
- Timestamp:
- May 4, 2018, 12:56:52 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/FastGraphics/UGGraphics.pas
r34 r35 51 51 TGConvertFromColor = function (Color: TColor): TGColor of object; 52 52 TGGetColor = function (Position: TPoint): TGColor of object; 53 PGColor = ^TGColor; 53 54 protected 54 55 FData: PByte; 55 56 FSize: TPoint; 56 57 FCanvas: TGCanvas<TGColor>; 58 FBytesPerLine: Integer; 59 FBytesPerPixel: Integer; 57 60 function GetPixel(X, Y: Integer): TGColor; virtual; 58 61 function GetSize: TPoint; virtual; … … 66 69 procedure PaintToCanvas(Canvas: TCanvas; ColorConvertFunc: TGConvertColor); overload; 67 70 procedure PaintToCanvas(Canvas: TCanvas; Rect: TRect; ColorConvertFunc: TGConvertColor); overload; 68 procedure PaintToBitmap(Bitmap: TBitmap; Rect: TRect; ColorConvertFunc: TGConvertColor); 71 procedure PaintToBitmap(Bitmap: TBitmap; Pos: TPoint; ColorConvertFunc: TGConvertColor); overload; 72 procedure PaintToBitmap(Bitmap: TBitmap; Rect: TRect; ColorConvertFunc: TGConvertColor); overload; 69 73 procedure LoadFromCanvas(Canvas: TCanvas; ColorConvertFunc: TGConvertFromColor); overload; 70 74 procedure LoadFromBitmap(Bitmap: TBitmap; ColorConvertFunc: TGConvertFromColor); … … 96 100 end; 97 101 102 { TPixelPointer } 103 104 TPixelPointer = record 105 Base: Pointer; 106 Pixel: Pointer; 107 Line: Pointer; 108 BytesPerPixel: Integer; 109 BytesPerLine: Integer; 110 procedure NextLine; inline; // Move pointer to start of new base line 111 procedure NextPixel; inline; // Move pointer to next pixel 112 procedure SetXY(X, Y: Integer); inline; // Set pixel position relative to base 113 procedure SetX(X: Integer); inline; // Set horizontal pixel position relative to base 114 procedure Init(Bitmap: TRasterImage; BaseX: Integer = 0; BaseY: Integer = 0); inline; overload; 115 procedure Init(Base: Pointer; BytesPerLine, BytesPerPixel: Integer; BaseX: Integer = 0; BaseY: Integer = 0); inline; overload; 116 end; 117 98 118 99 119 implementation 100 120 121 { TPixelPointer } 122 123 procedure TPixelPointer.NextLine; inline; 124 begin 125 Line := Pointer(Line) + BytesPerLine; 126 Pixel := Line; 127 end; 128 129 procedure TPixelPointer.NextPixel; inline; 130 begin 131 Pixel := Pointer(Pixel) + BytesPerPixel; 132 end; 133 134 procedure TPixelPointer.SetXY(X, Y: integer); inline; 135 begin 136 Line := Pointer(Base) + Y * BytesPerLine; 137 SetX(X); 138 end; 139 140 procedure TPixelPointer.SetX(X: Integer); inline; 141 begin 142 Pixel := Pointer(Line) + X * BytesPerPixel; 143 end; 144 145 procedure TPixelPointer.Init(Bitmap: TRasterImage; BaseX: Integer = 0; 146 BaseY: Integer = 0); inline; 147 begin 148 Init(Bitmap.RawImage.Data, Bitmap.RawImage.Description.BytesPerLine, Bitmap.RawImage.Description.BitsPerPixel shr 3, BaseX, BaseY); 149 end; 150 151 procedure TPixelPointer.Init(Base: Pointer; BytesPerLine, BytesPerPixel: Integer; BaseX: Integer = 0; BaseY: Integer = 0); inline; overload; 152 begin 153 Self.BytesPerLine := BytesPerLine; 154 Self.BytesPerPixel := BytesPerPixel; 155 Self.Base := Pointer(Base + BaseX * BytesPerPixel + BaseY * BytesPerLine); 156 SetXY(0, 0); 157 end; 158 101 159 { TGPixmap } 102 160 … … 104 162 begin 105 163 CheckLimits(X, Y); 106 Move(PByte(FData + (X + Y * FSize.X) * SizeOf(TGColor))^, Result, SizeOf(TGColor));164 Move(PByte(FData + X * FBytesPerPixel + Y * FBytesPerLine)^, Result, SizeOf(TGColor)); 107 165 end; 108 166 … … 110 168 begin 111 169 CheckLimits(X, Y); 112 Move(AValue, PByte(FData + (X + Y * FSize.X) * SizeOf(TGColor))^, SizeOf(TGColor));170 Move(AValue, PByte(FData + X * FBytesPerPixel + Y * FBytesPerLine)^, SizeOf(TGColor)); 113 171 end; 114 172 … … 122 180 if (FSize.X <> AValue.X) and (FSize.Y <> AValue.Y) then begin 123 181 FSize := AValue; 124 ReAllocMem(FData, FSize.X * FSize.Y * SizeOf(TGColor)); 182 FBytesPerPixel := SizeOf(TGColor); 183 FBytesPerLine := AValue.X * FBytesPerPixel; 184 ReAllocMem(FData, FSize.X * FBytesPerLine); 125 185 end; 126 186 end; … … 128 188 constructor TGPixmap<TGColor>.Create; 129 189 begin 190 Size := Point(0, 0); 130 191 FCanvas := TGCanvas<TGColor>.Create; 131 192 FCanvas.Bitmap := Self; … … 195 256 end; 196 257 258 procedure TGPixmap<TGColor>.PaintToBitmap(Bitmap: TBitmap; Pos: TPoint; 259 ColorConvertFunc: TGConvertColor); 260 var 261 X, Y: Integer; 262 DstPtr: TPixelPointer; 263 SrcPtr: TPixelPointer; 264 begin 265 try 266 Bitmap.BeginUpdate(False); 267 DstPtr.Init(Bitmap); 268 SrcPtr.Init(FData, FBytesPerLine, FBytesPerPixel, Pos.X, Pos.Y); 269 for Y := 0 to Bitmap.Height - 1 do begin 270 for X := 0 to Bitmap.Width - 1 do begin 271 if ((X + Pos.X) >= 0) and ((X + Pos.X) < FSize.X) and 272 ((Y + Pos.Y) >= 0) and ((Y + Pos.Y) < FSize.Y) then begin 273 PInteger(DstPtr.Pixel)^ := ColorConvertFunc(PGColor(SrcPtr.Pixel)^); 274 end; 275 DstPtr.NextPixel; 276 SrcPtr.NextPixel; 277 end; 278 DstPtr.NextLine; 279 SrcPtr.NextLine; 280 end; 281 finally 282 Bitmap.EndUpdate(False); 283 end; 284 end; 285 197 286 procedure TGPixmap<TGColor>.PaintToBitmap(Bitmap: TBitmap; Rect: TRect; 198 287 ColorConvertFunc: TGConvertColor); 199 288 var 200 289 X, Y: Integer; 201 PixelPtr: PInteger; 202 PixelPtrMax: PInteger; 203 PixelPtrMin: PInteger; 204 PixelRowPtr: PInteger; 205 RawImage: TRawImage; 206 BytePerPixel: Integer; 290 DstPtr: TPixelPointer; 291 ZoomX: Single; 292 ZoomY: Single; 293 SrcX: Integer; 294 SrcY: Integer; 207 295 begin 208 296 try 209 297 Bitmap.BeginUpdate(False); 210 RawImage := Bitmap.RawImage; 211 PixelRowPtr := PInteger(RawImage.Data); 212 BytePerPixel := RawImage.Description.BitsPerPixel div 8; 213 PixelPtrMin := PixelRowPtr; 214 PixelPtrMax := PixelRowPtr + RawImage.Description.Width * RawImage.Description.Height * BytePerPixel; 298 DstPtr.Init(Bitmap); 299 ZoomX := Bitmap.Width / (Rect.Right - Rect.Left); 300 ZoomY := Bitmap.Height / (Rect.Bottom - Rect.Top); 215 301 for Y := 0 to Bitmap.Height - 1 do begin 216 PixelPtr := PixelRowPtr;302 SrcY := Trunc(Y / ZoomY + Rect.Top); 217 303 for X := 0 to Bitmap.Width - 1 do begin 218 if ((X + Rect.Left) >= 0) and ((X + Rect.Left) < FSize.X) and219 ((Y + Rect.Top) >= 0) and ((Y + Rect.Top) < FSize.Y) and220 ( PixelPtr < PixelPtrMax) and (PixelPtr >= PixelPtrMin) then begin221 P ixelPtr^ := ColorConvertFunc(Pixels[X + Rect.Left, Y + Rect.Top]);304 SrcX := Trunc(X / ZoomX + Rect.Left); 305 if (SrcX >= 0) and (SrcX < FSize.X) and 306 (SrcY >= 0) and (SrcY < FSize.Y) then begin 307 PInteger(DstPtr.Pixel)^ := ColorConvertFunc(Pixels[SrcX, SrcY]); 222 308 end; 223 Inc(PByte(PixelPtr), BytePerPixel);309 DstPtr.NextPixel; 224 310 end; 225 Inc(PByte(PixelRowPtr), RawImage.Description.BytesPerLine);311 DstPtr.NextLine; 226 312 end; 227 313 finally … … 248 334 var 249 335 X, Y: Integer; 250 PixelPtr: PInteger; 251 PixelPtrMax: PInteger; 252 PixelRowPtr: PInteger; 253 P: TPixelFormat; 254 RawImage: TRawImage; 255 BytePerPixel: Integer; 336 SrcPtr: TPixelPointer; 337 DstPtr: TPixelPointer; 256 338 begin 257 339 try 258 340 Bitmap.BeginUpdate(False); 259 RawImage := Bitmap.RawImage; 260 PixelRowPtr := PInteger(RawImage.Data); 261 BytePerPixel := RawImage.Description.BitsPerPixel div 8; 262 PixelPtrMax := PixelRowPtr + RawImage.Description.Width * RawImage.Description.Height * BytePerPixel; 341 SrcPtr.Init(Bitmap); 342 DstPtr.Init(FData, FBytesPerLine, FBytesPerPixel); 263 343 for Y := 0 to FSize.Y - 1 do begin 264 PixelPtr := PixelRowPtr;265 344 for X := 0 to FSize.X - 1 do begin 266 if (X >= 0) and (X < FSize.X) and (Y >= 0) and (Y < FSize.Y) and (PixelPtr < PixelPtrMax) then 267 Pixels[X, Y] := ColorConvertFunc(PixelPtr^); 268 Inc(PByte(PixelPtr), BytePerPixel); 345 if (X >= 0) and (X < FSize.X) and (Y >= 0) and (Y < FSize.Y) then 346 PInteger(DstPtr.Pixel)^ := ColorConvertFunc(PInteger(SrcPtr.Pixel)^); 347 SrcPtr.NextPixel; 348 DstPtr.NextPixel; 269 349 end; 270 Inc(PByte(PixelRowPtr), RawImage.Description.BytesPerLine); 350 SrcPtr.NextLine; 351 DstPtr.NextLine; 271 352 end; 272 353 finally … … 277 358 function TGPixmap<TGColor>.GetDataSize: Int64; 278 359 begin 279 Result := FSize. X * FSize.Y * SizeOf(TGColor);360 Result := FSize.Y * FBytesPerLine; 280 361 end; 281 362
Note:
See TracChangeset
for help on using the changeset viewer.