首页 > 其他分享 >delphi Image32 图像采样

delphi Image32 图像采样

时间:2024-07-01 22:52:38浏览次数:1  
标签:采样 ImagePanel img delphi displaySize Image32 displayRect margin Image

图像数据采样

 

 

代码:

  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

相关文章

  • 时间离散/重采样
    fromdatetimeimportdatetimeimoportnumpyasnpfromitertoolsimportproductclasstimeDiscrete():#时间格式的离散和对齐-计数def__init__(self,delta=30,dft='%Y-%m-%d%H:%M:%S'):self.delta=delta#重采样时间差分钟self.df......
  • 抽样之拒绝接受采样
    #以指数分布为例,进行接受拒绝采样#指数分布PDF=e^(-x)x>=0#我们选取x的范围为0-5,首先在x上随机生成100000个均匀分布的随机数,计算f(xi)#然后在指数分布最大值与最小值之间生成100000个均匀分布的随机数yi#比较f(xi)与yi,如果f(xi)<=yi则接受,否则不接受importnump......
  • ggplot2绘制采样地,手动批量指定颜色、性状、大小、设置图例
     001、原始数据LongitudeLatitudediqusubspenum-10439West_EuropeBos_taurus10-356West_EuropeBos_taurus30-351West_EuropeBos_taurus202-44Central_South_EuropeBos_taurus26245Central_South_EuropeBos_tauru......
  • 【机器学习】基于Softmax松弛技术的离散数据采样
    1.引言1.1.离散数据采样的意义离散数据采样在深度学习中起着至关重要的作用,它直接影响到模型的性能、泛化能力、训练效率、鲁棒性和解释性。首先,采样方法能够有效地平衡数据集中不同类别的样本数量,使得模型在训练时能够更均衡地学习各个类别的特征,从而避免因数据不平衡导......
  • 电压互感器(zmpt101b)交流电压采样
        交流电压采样是我们在控制逆变电路时重要的一环。有一种采样方法就是用电压互感器+运放将目标交流电压转化为单片机可以测量的电压(即控制在合适的大小内,并且均转化为正值)。    在淘宝上我们可以买到现成的互感器模块,如下图: 其原理图如下:感谢@qq_389......
  • 分享一个go源码的均匀采样底层实现原理
    //int31n也就是下面这个函数,跟上面Int31n效果是一样的.但是效率更高.算法不一样.这个算法非常精彩,效率也更高.//int31nreturns,asanint32,anon-negativepseudo-randomnumberinthehalf-openinterval[0,n).//nmustbe>0,butint31ndoesnotcheckthis;......
  • 数据采集与控制 > 声音与振动 > PCI8811,该板卡是一款为测试音频和振动信号而设计的高精
    每通道集成独立的IEPE激励源,可实现加速度传感器及麦克风等相关的信号调理。信息社会的发展,在很大程度上取决于信息与信号处理技术的先进性。数字信号处理技术的出现改变了信息与信号处理技术的整个面貌,而数据采集作为数字信号处理的必不可少的前期工作在整个数字系统中起到关......
  • Delphi 生成随机验证码
    Delphi生成随机验证码functionCodeImg(img:Timage):string; var  I,j,k: Integer;  vPoint: TPoint;  vLeft: Integer;  arrStr:array[1..36]ofstring;  strResult:string; begin  strResult:='';  arrStr[1]:=......
  • delphi:利用定时器读取串口返回数据
    定时器20毫秒运行一次,单字符读取,如果读取到就保存到全局变量receData中,否则就输出到文本框中,并重置receData。优点:单字符读取,解决了按长度读取的弊端,如果按长度读取,很多时候并不知道究竟要读取多长,有的时候能读取完整,有的时候只读取了部分。procedureTfrmLC.tmrReceDataTimer(S......
  • 基于全数字中频架构的低采样率频谱分析系统研究与实现(论文)
    目录第一章绪论III1.1课题来源及意义III1.2研究现状及发展态势III1.3课题研究内容III1.4论文特色IV第二章整体仿真与介绍52.1系统整体架构52.2系统整体模拟仿真52.3硬件开发平台选择与介绍6第三章数字下变频93.1信号下变频架构对比与选择93.2信......