Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution design - Image formats #384

Open
Lakritzator opened this issue Feb 20, 2022 · 5 comments
Open

Solution design - Image formats #384

Lakritzator opened this issue Feb 20, 2022 · 5 comments

Comments

@Lakritzator
Copy link
Member

Lakritzator commented Feb 20, 2022

In Greenshot before 1.3 all the image loading and saving is done by using System.Drawing (part of Windows Forms) which is GDI+. This also restricts the possible file formats, and any shortcomings of the file formats that are supported.

On top of this, the code paths for those formats were very interwoven, that means that if we wanted to add a new format by adding a new dependency making this possible, that would need to be very integrated and those may cause issues or have limited support.

GDI+ has limited support, the following formats are supported by Greenshot in 1.2:
".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff" (or ".tif") and finally ".ico".
The .ico format is enhanced by my own code, to help support a few more.
This is all documented here: https://docs.microsoft.com/en-us/dotnet/desktop/winforms/advanced/using-image-encoders-and-decoders-in-managed-gdi?view=netframeworkdesktop-4.8

The formats above can be opened from file, using the tray icon, or dragged / copied upon the drawing surface of the editor.

Additionally there is .greenshot, which is in fact a PNG with customer stuff appended to it.
The way that format works, is actually a big issue as for that format we just serialize .NET classes, causing compatibility issues when we change something.
WHAT, REALLY? You might ask, yes, we never really made a real defined file format, we just didn't get to it.

There are two additional formats, which someone were supported:
.emf & .wmf
These image files contain some sort of vector graphics, and you were able to use them like the other formats, BUT the image was rasterized (drawn to pixels) only once. So any advantages these formats would bring, was neglected.

In Greenshot 1.2 I added some basic SVG, as this was needed for JIRA icons. This is a vector graphics format, but the way it was implemented was similar to emf / wmf.

@Lakritzator
Copy link
Member Author

Lakritzator commented Feb 20, 2022

With Greenshot 1.3, I've rewritten most of the file output and input logic, using modularization it now is possible to easily add new file formats or improve the current ones.

This investment, mostly done in #385, will pay out to for example feature request #347

What changed? I've added a new interface IFileFormatHandler, which will be used throughout Greenshot for handling many different file formats for different use-cases. All implementations are registered with a service provider during startup, when something is needed the best match is retrieved.

So IFileFormatHandler describes the use-case, which provide:

  • What extensions are supported for different actions (reading and writing).
  • Does it support a specific action for a certain extension
  • Save to stream
  • Load bitmap from stream
  • Load IDrawableContainer (that which is the basic drawable thing in the editor) from stream.
  • Every implementation can provide a priority, allowing the caller to find the best priority. e.g. GDI+ can handle .png but so can WPF, and also ImageSharp (proven better)

There are extension methods available to provide the basic logic of getting the best fit, but also retrying the next when there is an issue.

I also made a few implementations of IFileFormatHandler:

  • DefaultFileFormatHandler - the default .NET (GDI+) file format handler, which can read and write the GDI formats ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff" (or ".tif")
  • DibFileFormatHandler is for handling device-dependent bitmaps to/from the clipboard
  • GreenshotFileFormatHandler is for loading and saving .greenshot files
  • IconFileHandler is for loading and saving .ico files, due to custom logic this was more than the DefaultFileFormatHandler would have been able to, so that one doesn't do .ico.
  • MetafileFormatHandler (should probably been MetafileFileFormatHandler), which can read emf / wmf as bitmap OR as IDrawableContainer, which now is more intelligent as it will store the vector information and draw in the wanted size. Meaning you will always get the best quality.
  • SvgFileFormatHandler can load .svg files, and similar to the MetafileFormatHandler it will (depending on the action) make sure it draws to the correct size using the vector information, thus should always be sharp.
  • WpfFileFormatHandler uses the Windows Presentation Framework to read and write image files, as this uses WIC it can do some other file formats. Also depending on installed software, additional formats can be added. For this I've added some registry reading, which can figure out some of the supported formats. By default the following formats are supported for loading: ".jxr", ".dds", ".hdp", ".wdp", ".wmp", and of those we support ".jxr" (JPG-XR) for writing. The dynamic formats are added and only supported for reading, with my system these are: ".3fr, .ari, .arw, .bay, .cap, .cr2, .cr3, .crw, .dcs, .dcr, .drf, .eip, .erf, .fff, .iiq, .k25, .kdc, .mef, .mos, .mrw, .nef, .nrw, .orf, .ori, .pef, .ptx, .pxn, .raf, .raw, .rw2, .rwl, .sr2, .srf, .srw, .x3f, .dng, .arw, .cr2, .crw, .erf, .kdc, .mrw, .nef, .nrw, .orf, .pef, .raf, .raw, .rw2, .rwl, .sr2, .srw, .dng, .heic, .heif"

This doesn't cover webp, as was requested in #347. But it leaves the way open to add for example an ImageSharpFileFormatHandler which would bring:

  • Better meta-data handling
  • More efficient .PNG writing (smaller)
  • webp

And maybe more, it's a super interesting project.
Due to the size of the library, and some open topics on a few different PRs this has not been done yet.

@Lakritzator Lakritzator changed the title Solution design image formats Solution design - Image formats Feb 20, 2022
@Lakritzator
Copy link
Member Author

Besides having support for multiple new file formats, and better support for vector graphics in the editor, I've also added some additional logic which uses the new zoom in the editor to auto fit it when opening a file. Additionally adding files, by using draw & drop or copy & paste, to the editor will make sure these will fit better on the capture (before they might have been HUGE).

@Lakritzator
Copy link
Member Author

Actually there is one more file format supported, that is the Greenshot templates (.gst).
This is a file with only the part which contains the elements, as is at the end of the .greenshot file.
Note to me: This needs to be added to the GreenshotFileFormatHandler.

About the .greenshot file format, and .gst for that matter, this will be done via #375

@valdier1
Copy link

Webp would be a great feature, perhaps it can be done as an optional plugin? If size is a concern we can choose not to install but for those of us that use webp daily, it would be fantastic to skip a conversion step

@cedesse
Copy link

cedesse commented Jun 29, 2023

It's trivial to repeat this request about WebP support. And the answer is probably still the same, since GDI+ built-in encoders and decodes still haven't changed (https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/using-image-encoders-and-decoders-in-managed-gdi?view=netframeworkdesktop-4.8) ?

WebP is ideal for screenshots in emails and web pages. It will typically reduce the data size of emails by 50-100% or even more compared to JPG, so the need is very real.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants