图像数据采样
代码:
1 unit uFrmImageResampling; 2 3 interface 4 5 uses 6 Winapi.Windows, Winapi.Messages, Winapi.ShellAPI, // 7 System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, 8 Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, System.Types, System.Math, // 9 Img32, Img32.Panels, Img32.Resamplers, Img32.Vector, Img32.Extra, 10 Img32.Fmt.BMP, Img32.Fmt.PNG, Img32.Draw, Img32.Text, Img32.Transform; 11 12 type 13 TfrmImageResampling = class(TForm) 14 TabControl1: TTabControl; 15 StatusBar1: TStatusBar; 16 procedure FormCreate(Sender: TObject); 17 procedure TabControl1Change(Sender: TObject); 18 procedure FormDestroy(Sender: TObject); 19 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 20 private 21 boxDownsamplingLinkRect: TRect; 22 fontReader: TFontReader; 23 fontCache12: TFontCache; 24 fontCache16: TFontCache; 25 fontCache125: TFontCache; 26 ImagePanel: TImage32Panel; 27 private 28 procedure ImagePanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 29 procedure ImagePanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); 30 procedure ImagePanelKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 31 procedure ShowGeneralResamplers1; 32 procedure ShowGeneralResamplers2; 33 procedure ShowGeneralResamplers3; 34 procedure ShowGeneralResamplers4; 35 procedure ShowDownSampling; 36 end; 37 38 var 39 frmImageResampling: TfrmImageResampling; 40 41 implementation 42 43 {$R *.dfm} 44 {$R images3.res} 45 46 {$REGION '实现 StopWatch功能'} 47 48 type 49 TTimeRec = record 50 started: Boolean; 51 freq: TLargeInteger; 52 startTime: TLargeInteger; 53 cumulativeTime: double; 54 endTime: TLargeInteger; 55 end; 56 57 procedure ResetTimer(out timeRec: TTimeRec; startNow: Boolean = true); 58 begin 59 with timeRec do 60 begin 61 QueryPerformanceFrequency(freq); 62 //检索性能计数器的频率。 性能计数器的频率在系统启动时固定,并且在所有处理器中保持一致。 因此,只需在应用程序初始化时查询频率,并且可以缓存结果。 63 //作用:返回硬件支持的高精度计数器的频率。返回值:非零,硬件支持高精度计数器;零。硬件不支持。读取失败。 64 QueryPerformanceCounter(startTime); 65 //检索性能计数器的当前值,这是一个高分辨率 (<1us) 时间戳,可用于时间间隔度量。 66 //如果该函数成功,则返回值为非零值。 67 //如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。 在运行 Windows XP 或更高版本的系统上,函数将始终成功,因此永远不会返回零。 68 started := startNow; 69 cumulativeTime := 0; 70 if started then 71 QueryPerformanceCounter(startTime); 72 end; 73 end; 74 75 procedure PauseTimer(out timeRec: TTimeRec); 76 begin 77 with timeRec do 78 begin 79 if not started then 80 Exit; 81 QueryPerformanceCounter(endTime); 82 cumulativeTime := cumulativeTime + (endTime - startTime) / freq; 83 started := false; 84 end; 85 end; 86 87 procedure ResumeTimer(out timeRec: TTimeRec); 88 begin 89 with timeRec do 90 begin 91 if started then 92 Exit; 93 started := true; 94 QueryPerformanceCounter(startTime); 95 end; 96 end; 97 98 function StopTimer(timeRec: TTimeRec): double; 99 begin 100 PauseTimer(timeRec); 101 with timeRec do 102 begin 103 QueryPerformanceCounter(endTime); 104 Result := cumulativeTime; 105 end; 106 end; 107 108 {$ENDREGION} 109 110 //================================ 111 112 const 113 boxDownSamplingUrl = 'https://angusj.com/image32/Docs/Units/' + 'Img32.Resamplers/Routines/BoxDownSampling.htm'; 114 boxDownSamplingText = 'See - BoxDownSampling'; 115 116 var 117 // when performing multiple transformations then using a matrix 118 // that combines these into a single transformation will be faster 119 //当执行多个变换时,然后使用矩阵 120 //将这些结合到一个单一的转换中会更快 121 // useMatix = false; 122 useMatix: Boolean = true; //true 可能会有一些 范围检查错误,及数值溢出错误,己修改(条件编译部分程序禁止检查) 123 124 procedure TfrmImageResampling.FormCreate(Sender: TObject); 125 begin //Arial:显示不了中文字 Arial Unicode MS:可以显示中文 126 self.BorderStyle := bsNone; 127 FontManager.Load('Arial Unicode MS', 800); 128 fontReader := FontManager.GetFont('Arial Unicode MS'); 129 fontCache12 := TFontCache.Create(fontReader, DPIAware(12)); 130 fontCache16 := TFontCache.Create(fontReader, DPIAware(16)); 131 fontCache125 := TFontCache.Create(fontReader, DPIAware(125)); 132 133 ImagePanel := TImage32Panel.Create(self); 134 ImagePanel.BorderWidth := 0; //默认有个大边框,这里去掉 135 ImagePanel.Parent := TabControl1; 136 ImagePanel.Align := alClient; 137 ImagePanel.OnMouseDown := ImagePanelMouseDown; 138 ImagePanel.OnMouseMove := ImagePanelMouseMove; 139 ImagePanel.OnKeyDown := ImagePanelKeyDown; 140 ActiveControl := ImagePanel; 141 142 with ImagePanel.InnerClientRect do 143 ImagePanel.Image.SetSize(Width, Height); 144 TabControl1Change(nil); 145 end; 146 147 procedure TfrmImageResampling.FormDestroy(Sender: TObject); 148 begin 149 fontCache12.Free; 150 fontCache16.Free; 151 fontCache125.Free; 152 end; 153 154 procedure TfrmImageResampling.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 155 begin //这里触发不了 156 if (Key = VK_F5) and (TabControl1.TabIndex = 1) then // F5 => refresh 157 ShowGeneralResamplers2; 158 end; 159 160 procedure TfrmImageResampling.ImagePanelKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 161 begin //用这里触发 162 if (TabControl1.TabIndex = 1) then 163 begin 164 if (Key = VK_F5) then // F5 => refresh 165 begin 166 ShowGeneralResamplers2; 167 end 168 else if (Key = VK_F6) then 169 begin 170 useMatix := not useMatix; 171 ShowGeneralResamplers2; 172 end; 173 end 174 else if (TabControl1.TabIndex = 2) then 175 begin 176 if (Key = VK_F5) then 177 begin 178 ShowGeneralResamplers3; 179 end 180 else if (Key = VK_F6) then 181 begin 182 useMatix := not useMatix; 183 ShowGeneralResamplers3; 184 end; 185 end; 186 187 end; 188 189 procedure TfrmImageResampling.ImagePanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 190 var 191 pt: TPoint; 192 begin //这里用来点击连接的 193 if (TabControl1.TabIndex <> 4) then 194 Exit; 195 pt := ImagePanel.ClientToImage(System.Types.Point(X, Y)); 196 if PtInRect(boxDownsamplingLinkRect, pt) then 197 ShellExecute(0, 'open', PChar(boxDownSamplingUrl), nil, nil, SW_SHOWNORMAL); 198 end; 199 200 procedure TfrmImageResampling.ImagePanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); 201 var 202 pt: TPoint; 203 begin //这里用来判断连接的 204 if (TabControl1.TabIndex <> 4) then 205 Exit; 206 pt := ImagePanel.ClientToImage(System.Types.Point(X, Y)); 207 if PtInRect(boxDownsamplingLinkRect, pt) then 208 ImagePanel.Cursor := crHandPoint 209 else 210 ImagePanel.Cursor := crDefault; 211 end; 212 213 procedure TfrmImageResampling.ShowDownSampling; 214 var 215 margin: integer; 216 lineHt: integer; 217 img: TImage32; 218 dstRect: TRect; 219 pt: TPoint; 220 begin 221 ImagePanel.Image.Clear; //清除图像 222 223 margin := DPIAware(15); 224 lineHt := DPIAware(16); 225 img := TImage32.Create; 226 try 227 // 显示图像1到指定区域 228 img.LoadFromResource('TEXTONPATH', 'PNG'); //从资源中加载图片 229 img.CropTransparentPixels; //裁剪透明像素 230 with ImagePanel.InnerClientRect do 231 ImagePanel.Image.SetSize(Width, Height); 232 dstRect := ImagePanel.Image.Bounds; 233 System.Types.InflateRect(dstRect, -margin, -margin); 234 img.ScaleToFit(dstRect.Width * 3 div 4, dstRect.Height * 3 div 4); 235 dstRect.Right := dstRect.Left + img.Width; 236 dstRect.Bottom := dstRect.Top + img.Height; 237 ImagePanel.Image.Copy(img, img.Bounds, dstRect); //复制图形 238 239 // 显示图像2到指定区域 240 img.LoadFromResource('TEXTONPATH', 'PNG'); 241 // the image's specified resampler is usually ignored when downsampling 242 // UNLESS the compiler conditional USE_DOWNSAMPLER_AUTOMATICALLY has 243 // been disabled. (See BoxDownsampling for more info.) 244 img.Resampler := rBicubicResampler; 245 img.Scale(0.2); 246 dstRect.Top := dstRect.Bottom - img.Height; 247 dstRect.Left := img.Width + margin; 248 dstRect.Right := dstRect.Left + img.Width; 249 ImagePanel.Image.Copy(img, img.Bounds, dstRect); 250 251 // 绘制文字连接 252 pt.X := dstRect.Right + margin; 253 pt.Y := dstRect.Bottom - lineHt * 2; 254 boxDownsamplingLinkRect.Left := pt.X; 255 boxDownsamplingLinkRect.Bottom := pt.Y; 256 boxDownsamplingLinkRect.Top := pt.Y - lineHt; 257 boxDownsamplingLinkRect.Right := boxDownsamplingLinkRect.Left + Ceil(fontCache12.GetTextWidth(boxDownSamplingText)); 258 DrawText(ImagePanel.Image, pt.X, pt.Y, boxDownSamplingText, fontCache12, clBlue32); //连接的文字 259 finally 260 img.Free; 261 end; 262 end; 263 264 procedure TfrmImageResampling.ShowGeneralResamplers1; 265 var 266 displaySize: integer; 267 preRotatedSize: integer; 268 margin, dpi8: integer; 269 topOffset: integer; 270 angle: double; 271 img: TImage32; 272 rec, displayRect: TRect; 273 begin 274 dpi8 := DPIAware(8); 275 276 margin := DPIAware(10); 277 displaySize := DPIAware(110); 278 topOffset := DPIAware(60); 279 angle := DegToRad(-15); 280 displayRect := System.Types.Rect(margin, margin + topOffset, margin + displaySize, margin + displaySize + topOffset); 281 282 rec := GetRotatedRectBounds(displayRect, angle); 283 preRotatedSize := Round(displaySize * displaySize / rec.Width); 284 285 ImagePanel.Image.Clear; //清除 286 287 //绘制一些文本 288 DrawText(ImagePanel.Image, margin, margin + DpiAware(13), 'Scale 3x3 image then scale and rotate 3x3 image', fontCache16); 289 DrawText(ImagePanel.Image, margin, topOffset - dpi8, 'rNearestResampler', fontCache12); 290 DrawText(ImagePanel.Image, margin * 5 + displaySize * 2, topOffset - dpi8, 'rBilinearResampler', fontCache12); 291 DrawText(ImagePanel.Image, margin, topOffset - dpi8 + displaySize + margin * 6, 'rWeightedBilinear', fontCache12); 292 DrawText(ImagePanel.Image, margin * 5 + displaySize * 2, topOffset - dpi8 + displaySize + margin * 6, 'rBicubicResampler', fontCache12); 293 294 img := TImage32.Create; 295 try 296 // rNearestResampler 最近的重采样器 297 img.SetSize(3, 3); 298 img.Clear(clBlue32); 299 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 300 img.Resampler := rNearestResampler; //最近的重采样器 301 img.Resize(displaySize, displaySize); 302 ImagePanel.Image.Copy(img, img.Bounds, displayRect); //小图形,复制成大图形 303 TranslateRect(displayRect, displaySize + margin, 0); 304 305 img.SetSize(3, 3); 306 img.Clear(clBlue32); 307 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 308 img.Resize(preRotatedSize, preRotatedSize); //旋转后复制成大图形 309 img.Rotate(angle); 310 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 311 TranslateRect(displayRect, displaySize + margin * 3, 0); 312 313 // rBilinearResampler 双线性重采样器 314 315 img.SetSize(3, 3); 316 img.Clear(clBlue32); 317 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 318 img.Resampler := rBilinearResampler; //最近的重采样器 319 img.Resize(displaySize, displaySize); 320 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 321 TranslateRect(displayRect, displaySize + margin, 0); 322 323 img.SetSize(3, 3); 324 img.Clear(clBlue32); 325 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 326 img.Resize(preRotatedSize, preRotatedSize); 327 img.Rotate(angle); //旋转 328 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 329 TranslateRect(displayRect, -displayRect.Left + margin, displaySize + margin * 6); 330 331 // rWeightedBilinear //加权双线性 332 333 img.SetSize(3, 3); 334 img.Clear(clBlue32); 335 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 336 img.Resampler := rWeightedBilinear; //加权双线性 337 img.Resize(displaySize, displaySize); 338 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 339 TranslateRect(displayRect, displaySize + margin, 0); 340 341 img.SetSize(3, 3); 342 img.Clear(clBlue32); 343 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 344 img.Resize(preRotatedSize, preRotatedSize); 345 img.Rotate(angle); //旋转 346 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 347 TranslateRect(displayRect, displaySize + margin * 3, 0); 348 349 // rBicubicResampler 双立方体重采样器 350 351 img.SetSize(3, 3); 352 img.Clear(clBlue32); 353 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 354 img.Resampler := rBicubicResampler; //双立方体重采样器 355 img.Resize(displaySize, displaySize); 356 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 357 TranslateRect(displayRect, displaySize + margin, 0); 358 359 img.SetSize(3, 3); 360 img.Clear(clBlue32); 361 img.FillRect(System.Types.Rect(1, 1, 2, 2), clRed32); 362 img.Resize(preRotatedSize, preRotatedSize); 363 img.Rotate(angle); //旋转 364 //img.SaveToFile('c:\temp\test.png'); 365 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 366 finally 367 img.Free; 368 end; 369 end; 370 371 procedure TfrmImageResampling.ShowGeneralResamplers2; 372 var 373 imgDisplaySize: integer; 374 dpi5, dpi8, dpi18: integer; 375 scale: double; 376 i, margin: integer; 377 topOffset: integer; 378 angle: double; 379 img: TImage32; 380 rec, displayRect: TRect; 381 tr: TTimeRec; 382 mat: TMatrixD; 383 times: array[0..3] of double; 384 sText: UnicodeString; 385 const 386 loopCnt = 20; 387 begin 388 dpi5 := DPIAware(5); 389 dpi8 := DPIAware(8); 390 dpi18 := DPIAware(18); 391 margin := DPIAware(10); 392 imgDisplaySize := DPIAware(180); 393 topOffset := DPIAware(60); 394 displayRect := System.Types.Rect(margin, topOffset - margin, margin + imgDisplaySize, topOffset - margin + imgDisplaySize); 395 angle := DegToRad(60); 396 397 ImagePanel.Image.Clear; //清除 398 399 //显示文字 400 sText := Format('F5 刷新 循环 %d 次 F6:启用/停止矩阵算法 是否启用矩阵:%s ', [loopCnt, BoolToStr(useMatix, true)]); 401 DrawText(ImagePanel.Image, margin, margin + DpiAware(1), 'Scale and rotate a small bitmap image', fontCache16); 402 DrawText(ImagePanel.Image, margin, margin + DpiAware(20), sText, fontCache16); 403 // 404 Screen.Cursor := crHourGlass; //鼠标样式 [转换需要一定时间] 405 img := TImage32.Create; 406 try 407 img.LoadFromResource('BEETLE', 'PNG'); 408 rec := GetRotatedRectBounds(img.Bounds, angle); 409 scale := (imgDisplaySize / rec.Width); 410 mat := IdentityMatrix; 411 MatrixScale(mat, scale); 412 MatrixRotate(mat, NullPointD, angle); 413 // 1. 最近的重采样器 414 img.Resampler := rNearestResampler; 415 ResetTimer(tr, false); //重启记时器. 416 for i := 1 to loopCnt do //循环...(20次) 417 begin 418 img.LoadFromResource('BEETLE', 'PNG'); 419 ResumeTimer(tr); 420 if useMatix then 421 AffineTransformImage(img, mat) 422 else 423 begin 424 img.Scale(scale); 425 img.Rotate(angle); 426 end; 427 PauseTimer(tr); 428 end; 429 times[0] := StopTimer(tr) / loopCnt; 430 431 displayRect.Right := displayRect.Left + img.Width; 432 displayRect.Bottom := displayRect.Top + img.Height; 433 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 434 TranslateRect(displayRect, imgDisplaySize + margin * 3, 0); 435 //2.双线性重采样器 //Img32.Resamplers 单元有 Range Check 己修改(MY_BilinearResample,否则,可能会提示错误) 436 // //Img32.Transform 单元有 Overflow Checking 己修改(MY_OverflowChecking,否则,可能会提示溢出错误) 437 img.Resampler := rBilinearResampler; 438 ResetTimer(tr, false); 439 for i := 1 to loopCnt do //循环...(20次) 440 begin 441 img.LoadFromResource('BEETLE', 'PNG'); 442 ResumeTimer(tr); 443 if useMatix then 444 AffineTransformImage(img, mat) 445 else 446 begin 447 img.Scale(scale); 448 img.Rotate(angle); 449 end; 450 PauseTimer(tr); 451 end; 452 times[1] := StopTimer(tr) / loopCnt; 453 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 454 TranslateRect(displayRect, -displayRect.Left + margin, imgDisplaySize); 455 //3. 加权双线性 456 img.Resampler := rWeightedBilinear; 457 ResetTimer(tr, false); 458 for i := 1 to loopCnt do //循环...(20次) 459 begin 460 img.LoadFromResource('BEETLE', 'PNG'); 461 ResumeTimer(tr); 462 if useMatix then 463 AffineTransformImage(img, mat) 464 else 465 begin 466 img.Scale(scale); 467 img.Rotate(angle); 468 end; 469 PauseTimer(tr); 470 end; 471 times[2] := StopTimer(tr) / loopCnt; 472 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 473 TranslateRect(displayRect, imgDisplaySize + margin * 5, 0); 474 //双立方体重采样器 475 img.Resampler := rBicubicResampler; 476 ResetTimer(tr, false); 477 for i := 1 to loopCnt do //循环...(20次) 478 begin 479 img.LoadFromResource('BEETLE', 'PNG'); 480 ResumeTimer(tr); 481 if useMatix then 482 AffineTransformImage(img, mat) 483 else 484 begin 485 img.Scale(scale); 486 img.Rotate(angle); 487 end; 488 PauseTimer(tr); 489 end; 490 times[3] := StopTimer(tr) / loopCnt; 491 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 492 TranslateRect(displayRect, imgDisplaySize + margin * 5, 0); 493 //img.SaveToFile('c:\temp\resampling_bc.png'); 494 finally 495 img.Free; 496 Screen.Cursor := crDefault; 497 end; 498 499 //显示一些文本 500 DrawText(ImagePanel.Image, margin, topOffset - dpi8, 'rNearestResampler', fontCache12); 501 DrawText(ImagePanel.Image, margin, topOffset + dpi5, 'Fast, but also pixelated', fontCache12); 502 DrawText(ImagePanel.Image, margin, topOffset + dpi18, Format('%1.2n msec', [times[0] * 1e3]), fontCache12); 503 504 DrawText(ImagePanel.Image, margin * 5 + imgDisplaySize, topOffset - dpi8, 'rBilinearResampler', fontCache12); 505 DrawText(ImagePanel.Image, margin * 5 + imgDisplaySize, topOffset + dpi5, 'Note blurring', fontCache12); 506 DrawText(ImagePanel.Image, margin * 5 + imgDisplaySize, topOffset + dpi18, Format('%1.2n msec', [times[1] * 1e3]), fontCache12); 507 508 DrawText(ImagePanel.Image, margin, topOffset - dpi8 + imgDisplaySize, 'rWeightedBilinear', fontCache12); 509 DrawText(ImagePanel.Image, margin, topOffset + dpi5 + imgDisplaySize, 'Very mildly pixelated and blurred', fontCache12); 510 DrawText(ImagePanel.Image, margin, topOffset + dpi18 + imgDisplaySize, Format('%1.2n msec', [times[2] * 1e3]), fontCache12); 511 512 DrawText(ImagePanel.Image, margin * 5 + imgDisplaySize, topOffset - dpi8 + imgDisplaySize, 'rBicubicResampler', fontCache12); 513 DrawText(ImagePanel.Image, margin * 5 + imgDisplaySize, topOffset + dpi5 + imgDisplaySize, 'Slow, but no pixelation or blurring', fontCache12); 514 DrawText(ImagePanel.Image, margin * 5 + imgDisplaySize, topOffset + dpi18 + imgDisplaySize, Format('%1.2n msec', [times[3] * 1e3]), fontCache12); 515 516 end; 517 518 procedure TfrmImageResampling.ShowGeneralResamplers3; 519 var 520 i, displaySize: integer; 521 preRotatedSize: integer; 522 margin, dpi8: integer; 523 topOffset: integer; 524 angle: double; 525 img: TImage32; 526 rec, displayRect: TRect; 527 mat: TMatrixD; 528 sText:UnicodeString; 529 begin 530 dpi8 := DPIAware(8); 531 532 margin := DPIAware(10); 533 displaySize := DPIAware(110); 534 topOffset := DPIAware(60); 535 angle := DegToRad(-15); 536 displayRect := System.Types.Rect(margin, margin + topOffset, margin + displaySize, margin + topOffset + displaySize); 537 538 rec := GetRotatedRectBounds(displayRect, angle); 539 preRotatedSize := Round(displaySize * displaySize / rec.Width); 540 mat := IdentityMatrix; 541 // initial image will be 100 wide and 1 high 542 MatrixScale(mat, preRotatedSize / 100, preRotatedSize); 543 MatrixRotate(mat, NullPointD, angle); 544 545 ImagePanel.Image.Clear; //清除 546 547 //显示一些文本 548 sText := Format('F5 刷新 F6:启用/停止矩阵算法 是否启用矩阵:%s ', [BoolToStr(useMatix, true)]); 549 DrawText(ImagePanel.Image, margin, margin + DpiAware(1), 'Scale 100x1 image, then scale and rotate the same image', fontCache16); 550 DrawText(ImagePanel.Image, margin, margin + DpiAware(20), sText, fontCache16); 551 DrawText(ImagePanel.Image, margin, topOffset - dpi8, 'rNearestResampler', fontCache12); 552 DrawText(ImagePanel.Image, margin * 5 + displaySize * 2, topOffset - dpi8, 'rBilinearResampler', fontCache12); 553 DrawText(ImagePanel.Image, margin, topOffset - dpi8 + displaySize + margin * 6, 'rWeightedBilinear', fontCache12); 554 DrawText(ImagePanel.Image, margin * 5 + displaySize * 2, topOffset - dpi8 + displaySize + margin * 6, 'rBicubicResampler', fontCache12); 555 556 img := TImage32.Create; 557 try 558 // rNearestResampler 最近的重采样器 559 img.SetSize(100, 1); 560 for i := 0 to 99 do 561 img.Pixels[i] := RainbowColor(i / 100); 562 img.Resampler := rNearestResampler; 563 img.Resize(displaySize, displaySize); 564 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 565 TranslateRect(displayRect, displaySize + margin, 0); 566 567 img.SetSize(100, 1); 568 for i := 0 to 99 do 569 img.Pixels[i] := RainbowColor(i / 100); //彩虹渐变色. 570 if useMatix then 571 AffineTransformImage(img, mat, true) 572 else 573 begin 574 img.Resize(preRotatedSize, preRotatedSize); 575 img.Rotate(angle); 576 end; 577 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 578 TranslateRect(displayRect, displaySize + margin * 3, 0); 579 580 // rBilinearResampler 双线性重采样器 581 582 img.SetSize(100, 1); 583 for i := 0 to 99 do 584 img.Pixels[i] := RainbowColor(i / 100); 585 img.Resampler := rBilinearResampler; 586 img.Resize(displaySize, displaySize); 587 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 588 TranslateRect(displayRect, displaySize + margin, 0); 589 590 img.SetSize(100, 1); 591 for i := 0 to 99 do 592 img.Pixels[i] := RainbowColor(i / 100); 593 if useMatix then 594 AffineTransformImage(img, mat, true) 595 else 596 begin 597 img.Resize(preRotatedSize, preRotatedSize); 598 img.Rotate(angle); 599 end; 600 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 601 TranslateRect(displayRect, -displayRect.Left + margin, displaySize + margin * 6); 602 603 // rWeightedBilinear 加权双线性 604 605 img.SetSize(100, 1); 606 for i := 0 to 99 do 607 img.Pixels[i] := RainbowColor(i / 100); 608 img.Resampler := rWeightedBilinear; 609 img.Resize(displaySize, displaySize); 610 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 611 TranslateRect(displayRect, displaySize + margin, 0); 612 613 img.SetSize(100, 1); 614 for i := 0 to 99 do 615 img.Pixels[i] := RainbowColor(i / 100); 616 if useMatix then 617 AffineTransformImage(img, mat, true) 618 else 619 begin 620 img.Resize(preRotatedSize, preRotatedSize); 621 img.Rotate(angle); 622 end; 623 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 624 TranslateRect(displayRect, displaySize + margin * 3, 0); 625 626 // rBicubicResampler 双立方体重采样器 627 628 img.SetSize(100, 1); 629 for i := 0 to 99 do 630 img.Pixels[i] := RainbowColor(i / 100); 631 img.Resampler := rBicubicResampler; 632 img.Resize(displaySize, displaySize); 633 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 634 TranslateRect(displayRect, displaySize + margin, 0); 635 636 img.SetSize(100, 1); 637 for i := 0 to 99 do 638 img.Pixels[i] := RainbowColor(i / 100); 639 if useMatix then 640 AffineTransformImage(img, mat, true) 641 else 642 begin 643 img.Resize(preRotatedSize, preRotatedSize); 644 img.Rotate(angle); 645 end; 646 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 647 648 finally 649 img.Free; 650 end; 651 652 end; 653 654 procedure TfrmImageResampling.ShowGeneralResamplers4; 655 var 656 displaySize: integer; 657 preRotatedSize: integer; 658 margin, dpi8: integer; 659 topOffset: integer; 660 angle: double; 661 img: TImage32; 662 rec, displayRect: TRect; 663 begin 664 dpi8 := DPIAware(8); 665 666 margin := DPIAware(10); 667 displaySize := DPIAware(110); 668 topOffset := DPIAware(60); 669 angle := DegToRad(-15); 670 displayRect := System.Types.Rect(margin, margin + topOffset, margin + displaySize, margin + displaySize + topOffset); 671 672 rec := GetRotatedRectBounds(displayRect, angle); 673 preRotatedSize := Round(displaySize * displaySize / rec.Width); 674 675 ImagePanel.Image.Clear; //清除 676 //显示一些文字 677 DrawText(ImagePanel.Image, margin, margin + DpiAware(13), 'Scale and rotate 1x1 image then scale and rotate 2x2 image', fontCache16); 678 DrawText(ImagePanel.Image, margin, topOffset - dpi8, 'rNearestResampler', fontCache12); 679 DrawText(ImagePanel.Image, margin * 5 + displaySize * 2, topOffset - dpi8, 'rBilinearResampler', fontCache12); 680 DrawText(ImagePanel.Image, margin, topOffset - dpi8 + displaySize + margin * 6, 'rWeightedBilinear', fontCache12); 681 DrawText(ImagePanel.Image, margin * 5 + displaySize * 2, topOffset - dpi8 + displaySize + margin * 6, 'rBicubicResampler', fontCache12); 682 683 img := TImage32.Create; 684 try 685 // rNearestResampler 最近的重采样器 686 img.SetSize(1, 1); 687 img.Pixels[0] := clBlue32; 688 img.Resampler := rNearestResampler; 689 img.Resize(preRotatedSize, preRotatedSize); 690 img.Rotate(angle); 691 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 692 TranslateRect(displayRect, displaySize + margin, 0); 693 694 img.SetSize(2, 2); 695 img.Pixels[0] := clLime32; 696 img.Pixels[1] := clAqua32; 697 img.Pixels[2] := clYellow32; 698 img.Pixels[3] := clFuchsia32; 699 img.Resize(preRotatedSize, preRotatedSize); 700 img.Rotate(angle); 701 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 702 TranslateRect(displayRect, displaySize + margin * 3, 0); 703 704 // rBilinearResampler 双线性重采样器 705 706 img.SetSize(1, 1); 707 img.Pixels[0] := clBlue32; 708 img.Resampler := rBilinearResampler; 709 img.Resize(displaySize, displaySize); 710 img.Rotate(angle); 711 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 712 TranslateRect(displayRect, displaySize + margin, 0); 713 714 img.SetSize(2, 2); 715 img.Pixels[0] := clLime32; 716 img.Pixels[1] := clAqua32; 717 img.Pixels[2] := clYellow32; 718 img.Pixels[3] := clFuchsia32; 719 img.Resize(preRotatedSize, preRotatedSize); 720 img.Rotate(angle); 721 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 722 TranslateRect(displayRect, -displayRect.Left + margin, displaySize + margin * 6); 723 724 // rWeightedBilinear 加权双线性 725 726 img.SetSize(1, 1); 727 img.Pixels[0] := clBlue32; 728 img.Resampler := rWeightedBilinear; 729 img.Resize(displaySize, displaySize); 730 img.Rotate(angle); 731 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 732 TranslateRect(displayRect, displaySize + margin, 0); 733 734 img.SetSize(2, 2); 735 img.Pixels[0] := clLime32; 736 img.Pixels[1] := clAqua32; 737 img.Pixels[2] := clYellow32; 738 img.Pixels[3] := clFuchsia32; 739 img.Resize(preRotatedSize, preRotatedSize); 740 img.Rotate(angle); 741 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 742 TranslateRect(displayRect, displaySize + margin * 3, 0); 743 744 // rBicubicResampler 双立方体重采样器 745 746 img.SetSize(1, 1); 747 img.Pixels[0] := clBlue32; 748 img.Resampler := rBicubicResampler; 749 img.Resize(displaySize, displaySize); 750 img.Rotate(angle); 751 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 752 TranslateRect(displayRect, displaySize + margin, 0); 753 754 img.SetSize(2, 2); 755 img.Pixels[0] := clLime32; 756 img.Pixels[1] := clAqua32; 757 img.Pixels[2] := clYellow32; 758 img.Pixels[3] := clFuchsia32; 759 img.Resize(preRotatedSize, preRotatedSize); 760 img.Rotate(angle); 761 //img.SaveToFile('c:\temp\test.png'); 762 ImagePanel.Image.Copy(img, img.Bounds, displayRect); 763 finally 764 img.Free; 765 end; 766 end; 767 768 procedure TfrmImageResampling.TabControl1Change(Sender: TObject); 769 begin 770 ImagePanel.Scale := 1.0; 771 case TabControl1.TabIndex of 772 0: 773 ShowGeneralResamplers1; 774 1: 775 ShowGeneralResamplers2; 776 2: 777 ShowGeneralResamplers3; 778 3: 779 ShowGeneralResamplers4; 780 4: 781 ShowDownSampling; 782 end; 783 end; 784 785 end.
标签:采样,ImagePanel,img,delphi,displaySize,Image32,displayRect,margin,Image From: https://www.cnblogs.com/bluejade/p/18278997