图像数据采样

代码:

  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. 解密华为问界M7 Pro:智能出行的全新里程碑与技术亮点

    解读华为问界M7 Pro的智能里程碑 引言 2024年8月,智能出行领域迎来了一个激动人心的时刻--问界M7 Pro的重磅发布.这款智能SUV,不仅是华为在汽车领域的又一次大胆尝试,更是鸿蒙智行系统的 ...

  2. pc 移动端 双端切换-路由判断

    该封装主要以分类形式,实现对路由的简易区分.便于项目管理. 创建好项目,勾选路由插件,会自动生成 router文件夹与index.ts . index.ts 初始内容 创建项目 自动生成的router ...

  3. 光影精灵10 Win1+Ubuntu18.04 双系统 踩坑记录

    前言 第二年准备报名智能车了,当然还是创意组别.刚好买了今年新出的电脑光影精灵10,我想着也给它安一个双系统.但是没想到,相比于之前那个老电脑,新电脑的新硬件和驱动问题远比老电脑麻烦的多. 在经历了一 ...

  4. wxpython开发gui界面基础

    wxpython 开发gui 基础知识 一 .前言 记录使用wxpython开发gui工具吧.gui界面主要就是先布局,每个模块都是一个对象. 二.基础知识 import wx class MyFra ...

  5. dotnet 学习 CPF 框架笔记 了解 X11 里如何获取触摸信息

    本文记录我学习 CPF 框架的笔记,本文记录我阅读 CPF 框架,学习到了如何在 dotnet C# 里面获取到 X11 的触摸信息,获取到多指触摸以及触摸点的面积和触摸点压感等信息的方法 开始之前, ...

  6. Docker修改IP地址方法

    一.查看Docker IP root@master:/# ifconfig docker0 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu ...

  7. MySQL 切换 Oracle 问题整理

    MySQL 通常小写,Oracle 默认大写 ,查询过程中需加双引号,或者直接将MySQL 字段转换成大写 Springboot 配置 oracle连接 spring: datasource: url ...

  8. /proc/pids/status

    /proc/279/status是一个Linux内核中的文件,其中包含了当前进程的状态信息.每行的含义如下: Name: 进程的名称,例如"java"或"bash&quo ...

  9. Android复习(三)清单文件中的元素——>path-permission、permission、permission-group、permission-tree

    <path-permission> 语法: <path-permission android:path="string" android:pathPrefix=& ...

  10. MIL-STD-1553B总线通信模块(1553B板卡)

    MIL-STD-1553B总线通信模块(1553B板卡)产品具有以下特点: 1.产品覆盖多种接口CPCI/PXI/PCI/PC104/PC104+/USB等,满足用户不同平台的使用要求: 2.自主知识 ...