angusj
-
Content Count
132 -
Joined
-
Last visited
-
Days Won
8
Posts posted by angusj
-
-
3 hours ago, Anders Melander said:It looks to me as if there's a problem in your implementation... Here's what I get with a selection of Graphics32 kernels:
If you avoid using TAffineTransformation, and just use a resampler together with a renderer, then you do avoid this issue with pixelation.
(In my Image32 graphics library, I use affine transformations without a renderer.)
-
On 5/4/2023 at 6:40 PM, Anders Melander said:A fair comparison would be to compare the unscaled, downsampled results.
On 5/4/2023 at 9:36 PM, angusj said:Anyhow, I've just done a number of followup tests and I'll concede that I can't spot the difference between all 3 renderers when downsampling various images.
I've just had another look at resampling and specifically downsampling, and I'm back to my starting assertion that box downsampling does produce better quality images than general purpose resampling algorithms. However, I will concede that, because these downsampled images are generally much smaller, it's usually difficult to spot these differences.
For example:
This is the fruit image from above that has been resized to 1/3 original using a bicubic resampler:
This is the fruit image from above that has been resized to 1/3 original using a box downsampler:
Yes, it's hard to spot the differences unless you compare them with a decent image editor (or just zoom in using your web browser).
Yet here's a more extreme example of downsampling (scaled to 0.1 of original size) where the quality differences are very noticeable:Bicubic kernel resampler:
Box downsampler:
Original image:
And this does make sense when you understand the differences between these algorithms.
Consider downsampling an image to 1/3 its size (where each 3 x 3 grid of pixels will merge into a single pixel) ...
box downsampling will weigh every pixel equally in each 3 x 3 grid;
whereas general purpose kernel resamplers will heavily weight pixels that are closer to the middle of these 3 x 3 grids.
-
1 hour ago, Anders Melander said:Of course you can tweak Octree to work around the various issues is has but I feel that that is just polishing a turd.
Indeed, Octree does have significant limitations just as you've illustrated above.
Anyhow, here's the image reduced to 16 colors using (a slightly modified) median cut ...
-
53 minutes ago, Anders Melander said:How does it deal with this, when reduced from 17 to 16 colors:
Yes, several bugs needed fixing which I've done and just uploaded.
And I'm expecting you'll find a few more 😱.
Anyhow, thanks 😁.
-
This link to the Color Quantization unit in my own Delphi Graphics Library may also be useful to you.
The code there should be quite easy to adapt to Graphics32.
-
-
1 hour ago, David Heffernan said:I was blown away when VS offered me suggestions for the code I was writing.
MSVS does even better that that, it also suggests how to improve your code.
(Well it does for me, but perhaps not for you if your code can't be improved 😜.)
Over almost 30yrs, I've written a lot of very useful (ie reuseable) Delphi code, otherwise I would have ditched Delphi years ago.
- 1
-
-
2 hours ago, RaelB said:Is there any downside to using the filesystem in this scenario?
If you're only searching by filename or file type (*.jpg;*.png; etc) then the filesystem would suffice.
-
2 hours ago, Anders Melander said:Possibly, but the examples on that page are cooked to show the result you want;
LOL 🤣.
The pages perhaps are "cooked" but it wasn't intentional.
Anyhow, I've just done a number of followup tests and I'll concede that I can't spot the difference between all 3 renderers when downsampling various images.
I'm surprised and I'll need to refresh myself on the differences between these resamplers.
-
Looking at the image in the OP, it looks like FMX is using a nearest neighbour resampler, which is fast but poor quality. Certainly a bilinear or bicubic resampler would be much better, but for down sampling specifically, a BoxDownSampling resampler would be better still.
-
2 hours ago, Anders Melander said:Even if that would have been possible it wouldn't magically have become faster.
Yep, point taken.
-
Or you could make the bitshifting explicit :
inc(Cache.b, (ps.rgbBlue*alpha) shr 2);
And given that you're multiplying two bytes you could optimise this further by using a lookup table:
MulTable: array [Byte,Byte] of integer; //initialized in initialization section ... inc(Cache.b, MulTable[ps.rgbBlue, alpha] shr 2);
Edit: Oops, sorry, it appears that alpha is an integer, not a byte.
-
55 minutes ago, Renate Schaaf said:what happens to my three little stars?
4 😁
Edit: Perhaps it just means re-star-ting?
Edit2: It's very easy to rename a repository (via Settings) and you won't lose any stars!
- 1
- 1
-
3 hours ago, cltom said:As impressive as it is, this left me with the question, if the "market" for components/libraries in the Delphi space is big enough for so many solutions.
Honestly, the "market" for new Delphi components/libraries died about 10 years ago. The only people writing Delphi code now are old timers who've been around since Borland days, and before its lead developer got poached by Microsoft to write C#. So there's no longer a market for third-party Delphi developers, unless they've migrated their code into other languages (usually C#). The only "new" Delphi code is written by old hacks like me who aren't trying to make money out of this.
-
44 minutes ago, cltom said:I guess if all the brilliant people that have created these libraries aligned their efforts and focus on fewer but more consistently supported libraries, it would be a huge leap.
I was a contributor to Graphics32 for many years, but eventually Graphics32 had become too unweildy for me, and no longer useful over the longer term. My initial inclination was to do a major Graphics32 rewrite/update .. things like pruning 20!! various Line and Lineto methods from TBitmap32. These kind of made sense historically, but made absolutely no sense now. But when I started pruning these methods, I realised I was unravelling a Gordian's knot (ie an almost impossible task). So many of these methods had been interwoven inside other methods that I realised I'd be better off starting from scratch, which is what I did with Image32.
Edit: Not that I'm including myself in "all the brilliant people", just a long term programming hack 😜.
Edit2: And an expert is just someone who knows an awful lot about very little.
-
4 hours ago, Anders Melander said:When @angusj comes online he can chime in on that.
I've been lurking 😜, but when the OP mentioned TImage32, I was pretty sure he was referring to that class in Graphics32, rather than my own Image32 Graphics Library. While Image32 has many similarities with Graphics32, unlike Graphics32 it's cross-platform (using either FPC or Delphi's FMX framwork), and it also supports SVG images (reading not writing) which seems relevant given the parameters in this discussion.
17 hours ago, cltom said:What the application should do: from a library of images the user should be able to drag and drop elements to the main image. Those elements can then be moved, deleted, rotated, single or in groups.
Drag and drop isn't something that a graphics library should do, but but rotating (and resizing and transforming etc) most definitely are things any decent graphics library will do.
17 hours ago, cltom said:I gave it another go with an SVG component (because ideally the graphics library would come from svg-files). However, I dropped that SVG goal again since dissecting the svg elements would create another level of complexity. Even though the approach to have the library elements editable would stil be amazing.
SVG files, as in a library of SVG images, is completely separate from a Graphics (Display) Library, and I'd strongly recommend you source those separately. Anyhow, supporting SVG, even just reading them, is a huge task, but I think I've done a reasonable job of this in my Image32 library. (And Image32 is currently the preferred renderer for SVGIconImageList). As for editing SVG images, that is way beyond the means of a single developer. And while it may seem related to graphics display, it really isn't, and I seriously doubt you'd find a Graphics Libray (in any language) that supported editing SVG images.
17 hours ago, cltom said:I was pretty far with that approach with Graphics32, not quite there yet, though. ... I spend hours and hours trying to understand it with little success. Other than that I found the learning curve of GR32 brutally steep given that the documentation and demos are not easy to understand and there are pretty much no introduction like tutorials
While Graphics32 is still an excellent library, IMHO it's now showing it's age and the documentation hasn't been updated in a very long time. So unless you've been using the library for a long time (and there are many who have and still are), it won't be easy getting up to speed.
-
6 hours ago, vshvetsov said:Why is this happening?
I strongly suspect that this is because you haven't pre-multiplied the image before using AlphaBlend.
QuoteNote that the APIs use premultiplied alpha, which means that the red, green and blue channel values in the bitmap must be premultiplied with the alpha channel value. For example, if the alpha channel value is x, the red, green and blue channels must be multiplied by x and divided by 0xff prior to the call.
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-blendfunction
Here's a (rather poor) example of using AlphaBlend where the image is premultiplied.
There's also a PremultiplyAlpha function in my AlphaBitmaps.pas unit.
-
14 hours ago, vshvetsov said:1) I am programming in C++. The VCL provides C++ header files for using classes and functions. How will I use the Image32 (or Graphics32) library?
While I can't guarantee it, this is likely to help:
http://www.angusj.com/delphi/image32/Videos/cpp.mkv
14 hours ago, vshvetsov said:2) Can I use Image32 in a 64-bit Windows application?
Absolutely!
Edit: The 32 in the library name simply refers to image bits per pixel WRT how images are stored in memory. (And yes the library can read and write images to file using different bpp.)
-
I've attached a pretty old unit with numerous functions for managing semi-transparent VCL.Graphics.TBitmap controls.
However, unless your graphics needs are minimal, I strongly recommend you consider using an open source graphics library.
Two graphics libraries for Delphi I can recommend:
Graphics32: Multiple developers contributed over the last 20yrs and is widely used.
Image32: Recently developed by me. IMHO it's a lot simpler than Graphics32 while almost as fully featured.
- 2
-
-
1 hour ago, Fr0sT.Brutal said:BTW, is that you an original author?
Yep, the only author 😁.
-
6 hours ago, Fr0sT.Brutal said:What were users trying to find in that system folder?
I did ask because I was also curious. And a very brief part of the reply was that this user has written an add-on for anther program and states that "I want, eventually, to support multiple languages in the UI". I've really no idea how he plans to do that, and how accessing these files will help. Nevertheless in the past I have used Resource Hacker to glean dialog control ids, menus etc which I've altered dynamically from my own applications (via Windows' messaging system). And on rare occasions I've even altered application resources (modified the files) to better suit my needs - change a menu shortcut, enable a menu item, it tweak a dialog.
-
Yep, I twigged just after posting.
Poor image quality with DrawBitmap when destination is smaller than source
in FMX
Posted
It's a problem with the Graphics32 library too if TAffineTransformation is used to do the scaling.