图像数据采样

代码:

  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.

欢迎微信搜一搜 IT软件部落 关注公众号,你可以了解更详细的内容

欢儿微信扫码关注 IT软件部落 公众号,你可以了解更详细的内容

delphi Image32 图像采样的更多相关文章

  1. Delphi实现图像文本旋转特效完整代码

    Delphi实现图像文本旋转特效完整代码,本程序利用的控件主要是Panel 控件.Image 控件.Edit 控件.Label 控件和Button 控件.本程序的关键是利用Delphi 的bmp_ro ...

  2. OpenCV计算机视觉学习(12)——图像量化处理&图像采样处理(K-Means聚类量化,局部马赛克处理)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 准备 ...

  3. 问题-[Delphi]PixelFormat 图像颜色的数据格式

     PixelFormat: (指定图像中每个像素的颜色数据的格式) Delphi                                        微软                  ...

  4. Delphi制作图像特殊显示效果

    Delphi制作实现图像的各种显示效果,比如百叶窗.渐变.淡入淡出.水平交错.雨滴效果等,用鼠标点击“打开图像”按钮,可以选择图像文件导入到窗体中:点击其它各个按钮,可以实现图像显示特效,例如:点击“ ...

  5. Delphi存取图像完整解决方案

    http://blog.sina.com.cn/s/blog_693cf1cf0100plkq.html 对于涉及图像数据的数据库应用程序,图像数据的存取技术是一个关键.由于缺少技术文档及DEMO例程 ...

  6. delphi图形图像开发相关

    ①delphi的图形处理(doc) http://wenku.baidu.com/view/519df09951e79b89680226ee.html ②delphi的图形图像处理(ppt) http ...

  7. delphi 图像处理 图像左旋右旋

    procedure TDR_QM_ZP_Form.btn_ZXClick(Sender: TObject); //图像左旋 begin screen.Cursor := crhourglass; my ...

  8. delphi 图像处理 图像放大缩小

    procedure TDR_QM_ZP_Form.btn_FDClick(Sender: TObject); //图像放大 begin my_int1 := Trunc( my_int1 * 1.1) ...

  9. Delphi RichEx 图像

    unit RichEx; {2005-03-04 LiChengbinAdded:Insert bitmap or gif into RichEdit controls from source fil ...

  10. Delphi 图形图像对象组件

随机推荐

  1. 线性dp:最长公共子序列

    最长公共子序列 本文讲解的题与leetcode1143.最长公共子序列这题一样,阅读完可以挑战一下. 力扣题目链接 题目叙述: 给定两个字符串,输出其最长公共子序列,并输出它的长度 输入: ADABE ...

  2. 一键k8s企业级集群部署(以k8s的1.18.0版本为例)

    一.下载安装sealos wget https://github.com/fanux/sealos/releases/download/v3.2.0-beta.2/sealos && ...

  3. Linux 上的 AppImage、Snap、Flatpak 之间的区别和联系

    AppImage.Snap 和 Flatpak 是三种用于在 Linux 系统上分发和安装软件的包管理格式.它们都有助于解决软件依赖问题,使得应用程序可以在不同的 Linux 发行版上更容易地安装和运 ...

  4. 图穷匕见-所有反DDD模式都是垃圾

    本文书接上回<主观与客观,破除DDD凭经验魔咒>,关注公众号(老肖想当外语大佬)获取信息: 最新文章更新: DDD框架源码(.NET.Java双平台): 加群畅聊,建模分析.技术实现交流: ...

  5. Cookie的secure属性引起循环登录问题分析及解决方案

    作者:来自 vivo 互联网服务器团队- Wang Fei 单点登录作为公共组件,在各个公司内部被各个系统所广泛使用,但是在使用过程中我们会遇到各种各样的问题,其中循环登录问题就是一个比较经典的问题. ...

  6. RxJS 系列 – Scheduler

    前言 大部分情况下, RxJS 都是用来处理异步执行的. 比如 Ajax, EventListener 等等. 但其实, 它也是可以同步执行的, 甚至 by default 它就是同步执行的 (下面会 ...

  7. SQL Server 中的 NUL 设备/NIL设备

    SQL Server 中的 NUL 设备/NIL设备 在 SQL Server 中,有一个特殊的设备叫做 NUL(注意,不是 NULL),它类似于文件系统中的"黑洞".NUL 设备 ...

  8. 祝福 Eric 的下一段旅程,Flutter 3.3 现已发布

    Flutter 团队及社区成员们在美丽的城市挪威奥斯陆向您发来问候,我们正在此参加社区举办的 Flutter Vikings 活动,这是一个为期两天的开发技术交流盛会,虽然线下门票已经售罄,但您还可以 ...

  9. C语言位域的内存布局

    本文将先粗略介绍大小端,和大小端的测试方法,最后介绍位域的内存布局. 1. 大小端 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中. 小端模式,是指数据的高字节保存 ...

  10. Kubernetes基础(基本概念、架构)(十)

    一.介绍 Kubernetes(简称 K8S) 的出现是容器化技术发展的必然结果,容器化是应用程序级别的虚拟化,运行单个内核上有多个独立的用户空间实例,这些实例就是容器:容器提供了将应用程序的代码.运 ...