wadepm 0 Posted December 27, 2020 Hello! I am looking for a something that will scale bitmaps with a "nice" result. Something better than stretchdraw, which does exactly what I want but looks horrible. Thanks for your help. I hope I can return the favor some day... Share this post Link to post
Guest Posted December 27, 2020 Can "IconFontsImageList" and "SVGIconImageList" help you in this task? Share this post Link to post
wadepm 0 Posted December 27, 2020 After a quick look it appears (to me) that it is not what I am looking for. If I am reading the documentation correctly this is more for vector drawings? Share this post Link to post
Guest Posted December 27, 2020 did you see the Wiki page: https://github.com/EtheaDev/IconFontsImageList/wiki https://raw.githubusercontent.com/EtheaDev/IconFontsImageList/master/Demo/Images/DemoChangeSize.gif Share this post Link to post
FPiette 383 Posted December 27, 2020 4 hours ago, wadepm said: I am looking for a something that will scale bitmaps with a "nice" result. Something better than stretchdraw, which does exactly what I want but looks horrible. When making an image larger than his original resolution (enlargement) always gives a bad result. One way to mitigate this is to use bilinear interpolation but don't expect marvelous results. Making an image smaller than his original may be better but will also make it a little bit less nice. Suppressing pixel is the faster but worse solution. You need to merge several pixels into one and apply a weight on the existing pixel depending if it is far or near the new pixel position. Share this post Link to post
Guest Posted December 27, 2020 Of the options, the least worst, for me, would be to have an image of the largest size, and to scale down to an acceptable limit so as not to lose the desired quality at the minimum desired scale. Otherwise, you should buy an RTX 3080 (or another one from the 30xx series) and rent the NVIDia DLSS source code to help. 😂 😂 Share this post Link to post
dummzeuch 1505 Posted December 27, 2020 The JVCL also comes with some graphics manipulation functions. They look very similar to those in Graphics32 to me, so they might come from the same origin. Share this post Link to post
Guest Posted December 27, 2020 AphaControls from AlphaSkins does have a very nice API TFilterType = (ftBox {fastest}, ftTriangle, ftHermite, ftBell {if Dest is smaller}, ftSpline, ftLanczos3 {Slowest}, ftMitchell); procedure Stretch(const Src, Dst: TBitmap; const DstWidth, DstHeight: Integer; const Filter: TFilterType); And for me the algorithm called https://en.wikipedia.org/wiki/Mitchell-Netravali_filters is better as it does not lose contrast of the color as much as https://en.wikipedia.org/wiki/Lanczos_resampling Also (I didn't this this but tried it) one can use different low level and tweak for the above mentioned filters by utilizing DrawLine and CreateContributors, in other words you can tweak the default filter parameters, to do this you have to duplicate the Stretch function. Share this post Link to post
wadepm 0 Posted December 27, 2020 I am trying graphics32 right now. We'll see how it goes... Share this post Link to post
Anders Melander 1783 Posted December 28, 2020 On 12/27/2020 at 2:13 AM, wadepm said: I am looking for a something that will scale bitmaps with a "nice" result. I've attached an old library (from 1999) that can do it for you. I believe it's been incorporated in several other libraries over the years. I haven't used it since D5 so you might need to tweak it a bit for newer versions. Apart from that I would probably use Graphics32. resample.pas Share this post Link to post
wadepm 0 Posted December 28, 2020 Thanks Anders. I will take a look at it - it uses assembler and pointers(!) - both things I need to work on. Share this post Link to post
Anders Melander 1783 Posted December 28, 2020 44 minutes ago, wadepm said: it uses assembler and pointers(!) Remove the "{$define OPTIMIZED}" to disable the assembler. That probably won't work with the 64-bit compiler anyway. The pointers are unavoidable. But like I said, I would use Graphics32 instead. It has a high learning curve but the results are better and the library is maintained. Something like this: procedure Test; var Source: TBitmap32; Target: TBitmap32; Resampler: TKernelResampler; begin Target := TBitmap32.Create; try Source := TBitmap32.Create; try Source.LoadFromFile('foobar.bmp'); // Make new bitmap twice the size. You can also make it smaller. Target.SetSize(Source.Width*2, Source.Height*2); Resampler := TKernelResampler.Create(Source); // Resampler is now owned by TBitmap32 Resampler.Kernel := TLanczosKernel.Create; // Kernel is now owned by resampler // Stretch using kernel resampler Target.Draw(Target.BoundsRect, Source.BoundsRect, Source); finally Source.Free; end; // Do something with target bitmap... finally Target.Free; end; end; Share this post Link to post
wadepm 0 Posted December 28, 2020 (edited) What I want to do is even easier than that. I do everything with the "full size" bitmap and then assign it to an image on the form and just resize the image: TKernelResampler(Image.Bitmap.Resampler).Kernel := TMitchellKernel.create; Image.ScaleMode := smScale; Image.Scale := x; Works great. Edited December 28, 2020 by wadepm missing text Share this post Link to post
wadepm 0 Posted December 28, 2020 After working with it for awhile I see that the Graphics32 Image component does not respond to my code the same way the native image component does. May have to go back to working with bitmaps in the background, rescaling and then assigning to the image. Can I assign a tbitmap32 to a timage? Share this post Link to post
Anders Melander 1783 Posted December 28, 2020 1 hour ago, wadepm said: After working with it for awhile I see that the Graphics32 Image component does not respond to my code the same way the native image component does. What's the problem? 1 hour ago, wadepm said: Can I assign a tbitmap32 to a timage? No but you can assign a TBitmap32 to a TBitmap so this works: var Bitmap: TBitmap32; var Image: TImage; ... Image.Picture.Bitmap.Assign(Bitmap); Note though that if your TBitmap32 uses alpha (i.e. transparency) then you'll need to handle that somehow. Share this post Link to post
wadepm 0 Posted December 28, 2020 I have some routines that allow me to drag the image around inside of a scrollbox. When the image is full size it works fine, but when it is scaled its all choppy. I think your assignment will work nicely. Share this post Link to post
Anders Melander 1783 Posted December 28, 2020 6 minutes ago, wadepm said: I have some routines that allow me to drag the image around inside of a scrollbox. When the image is full size it works fine, but when it is scaled its all choppy. First of all you have to use a scale mode that doesn't control the position of the drawn image. Then it's pretty simple. Save the start cursor position in MouseDown, calculate the delta in MouseMove and scroll the image and end the drag in MouseUp. Here's some code: type TBitmapEditorPreview = class(TWinControl) private FImage: TImgView32; FStartPos: TPoint; FPanning: boolean; procedure ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); procedure ImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); public constructor Create(AOwner: TComponent); override; end; constructor TBitmapEditorPreview.Create(AOwner: TComponent); begin inherited Create(AOwner); FImage := TImgView32.Create(Self); FImage.Parent := Self; FImage.Align := alClient; FImage.Height := 200; FImage.SizeGrip := sgNone; FImage.OverSize := 16; FImage.ScaleMode := smScale; FImage.Centered := True; FImage.Bitmap.Delete; FImage.Bitmap.DrawMode := dmBlend; FImage.Bitmap.CombineMode := cmMerge; FImage.OnMouseDown := ImageMouseDown; FImage.OnMouseMove := ImageMouseMove; FImage.OnMouseUp := ImageMouseUp; end; procedure TBitmapEditorPreview.ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); begin if (ssLeft in Shift) then begin FStartPos := FImage.ControlToBitmap(Point(X, Y)); FImage.Cursor := crSizeAll; FPanning := True; end; end; procedure TBitmapEditorPreview.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); var NewPos: TPoint; dX, dY: integer; begin if (FPanning) then begin NewPos := FImage.ControlToBitmap(Point(X, Y)); dX := FStartPos.X - NewPos.X; dY := FStartPos.Y - NewPos.Y; if (dX <> 0) or (dY <> 0) then begin FImage.Scroll(dX, dY); FImage.Update; end; Changed; end; end; procedure TBitmapEditorPreview.ImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); begin if (FPanning) then begin FPanning := False; FImage.Cursor := crDefault; end; end; I've attached the unit I copied the above from. It's part of a larger framework so you will not be able to use it as-is. Here's what it looks like in action (it's the lower pane displaying your avatar): amBitmapEditorPreview.pas Share this post Link to post
wadepm 0 Posted December 29, 2020 What's the difference between TImage32 and TImgView32? Share this post Link to post
Anders Melander 1783 Posted December 29, 2020 13 minutes ago, wadepm said: What's the difference between TImage32 and TImgView32? Yeah, I figured that question would be coming To be honest I simply can't remember and the documentation doesn't provide any clues. I'll see if I can figure it out tomorrow unless someone else comes up with the answer. Share this post Link to post
Guest Posted December 29, 2020 Read the Documentation here: https://documentation.help/Graphics32/documentation.pdf Share this post Link to post
wadepm 0 Posted December 29, 2020 Thanks Anders. It seems it adds a scroll method at least... Share this post Link to post
wadepm 0 Posted December 29, 2020 OK, it appears TImgView32 is a combination of an image and a scroll box. Cool. Share this post Link to post
Guest Posted December 29, 2020 (edited) give a look in "Graphics32" by Zhao Yipeng https://raw.githubusercontent.com/zhaoyipeng/graphics32-for-Firemonkey/master/Snapshots/FMXGR32Demo.gif https://github.com/zhaoyipeng/graphics32-for-Firemonkey Quote Graphics32 is a graphics library for Delphi and Lazarus. Optimized for 32-bit pixel formats, it provides fast operations with pixels and graphic primitives. In most cases Graphics32 considerably outperforms the standard TBitmap/TCanvas methods. The documentation can be found at https://graphics32.github.io/Docs This is the Firemonkey fork of the Graphics32, It only support Firemonkey platform Edited December 29, 2020 by Guest Share this post Link to post
Anders Melander 1783 Posted December 29, 2020 10 hours ago, wadepm said: OK, it appears TImgView32 is a combination of an image and a scroll box. Cool. Yes that seems to be it; TImgView32 adds scrollbars and methods to scroll and center the image. Share this post Link to post