4.2 is now available!

This is a big update that focus on adding HEIC file format support, fixing performance with very large images, and upgrading and modernizing the functionality of many existing file types (JPEG, PNG, BMP, GIF, and TIFF). Many other quality of life issues have also been addressed or fixed.

If you’re using the Windows Store release, you should get the update automatically within the next 24 hours. You can also force an update check by following these instructions.

For the Classic release, you should be offered the update automatically within the next week or so. You can get the updater soon by going to ⚙ Settings → Updates → Check Now. You can also download and install it directly from the website.

It’s important to note that HEIC file format support requires two things: 1) you must be using Windows 10 v1809 or newer, and 2) you must install Microsoft’s HEVC Video Extensions from the Microsoft Store which costs $1. This is necessary due to HEVC being mired in licensing and patent royalty costs. If you want to find some HEIC images, look no further than your recent iPhone (7 or newer). Many newer Android devices also support it.

Most of the other built-in file types — BMP, GIF, PNG, JPEG, and TIFF — have been internally upgraded from using GDI+ to being built on top of WIC (Windows Imaging Component). BMP can now save 32-bit images with alpha transparency, while JPEG and PNG can now load and save much larger images, and TIFF now supports saving at 24-bit and 8-bit color depths ("Auto" is also now included).

On the performance side, I’ve rebuilt the data structures inside of the rendering engine that are used for keeping track of invalidation regions. These hold information about what parts of the image need to be rendered and then redrawn on the screen, either because the image has been changed (like with drawings or effects) or because of scrolling and zooming. In previous versions you couldn’t really work with very large images, starting around 32,000 x 32,000 pixels. Zooming in and out would result in a lot of slow performance, lag, and even complete hangs of the app for seconds — or more (at 60,000 pixels it could hang for 30-60 seconds or more!). Now this should all be completely fluid

Please note that a previous beta, 4.2 build 7121, included functionality that would automatically apply an image’s embedded color profile, thus converting the image to the sRGB color space and "fixing" its colors. The complexity of color management was much higher than expected, and thus it has been removed for now. It may come back in a future update but in a more substantial form. Check out Jeffrey Friedl’s excellent Digital-Image Color Spaces article for a good read on this subject.

Here is the complete list of changes since the 4.1.6 release:

  • New: Support for loading and saving HEIC images (Windows 10 v1809+ and codec installation is required). Please note that the "Quality" slider when saving is limited to a value of 90 (out of 100) while Microsoft investigates and fixes a crash in their codec.
  • New: Keyboard shortcuts for changing the current layer. You can see these in the Layers menu with the "Go to …" commands. Alt+PgUp/PgDown will go to the layer above/below, and Ctrl+Alt+PgUp/PgDown will go to the top/bottom layer.

  • Fixed: Optimized rendering engine to remove huge lag spikes (30+ seconds) when zooming or panning very large images (e.g. 32K x 32K pixels).
  • Improved: BMP now supports saving in 32-bit (with alpha!) and 8-bit indexed.

  • Improved: Added DIB and RLE file extensions to the BMP file type.

  • Improved: PNG, JPEG, and TIFF now support loading and saving of much larger images.
  • New: PNGs can now be saved as "interlaced".

  • Improved: JPEG now has configuration for the chroma subsampling mode (4:4:4, 4:2:2, and 4:2:0). The default is now 4:2:2 instead of the unconfigurable 4:2:0 of older versions. This may result in larger file sizes, but higher quality, as compared to previous versions.
  • Improved: TIFF now supports saving at 24-bit and 8-bit color depths.
  • Improved performance of saving for file types where "Auto" bit-depth is supported but is not the current choice.
  • Improved temporary memory usage when saving images at 8-bit color depth.
  • Improved: TGA images now load about 4x faster (thanks @null54!)
  • Fixed: 8-bit TGA images should now load correctly (thanks @null54 for the fix!)
  • Fixed: Some 32-bit TGA images were showing up as completely transparent due to their use of an obscure alpha channel type (thanks @null54 for the fix!)
  • Improved: Added error reporting to the Save Configuration dialog. Instead of just saying "Preview: (error)", you’ll also get the standard error dialog that includes the exception which can used for troubleshooting.

  • Fixed a number of performance issues in the Save Configuration dialog. Especially with large images, it should now be much faster to change options and to click OK/Cancel.
  • Fixed flickering in the Save Configuration dialog when changing options.
  • Fixed: Windows Explorer thumbnails for some image types (PDN, DDS, TGA) were not rendering their alpha (transparency) correctly, resulting in color skew. You may not see the effect of this fix for a particular image until that image is resaved or you clear Explorer’s thumbnail cache.
  • Fixed: Mouse cursors now scale appropriately for non-integer UI scales (e.g. 125% or 175%)

  • Fixed: AltGr should now work correctly with the Text tool. It will not trigger shortcuts like File -> Save All, or Edit -> Paste into New Image. (thanks @Bruce Bowyer-Smyth for the fix!)

  • Changed: Image->Resize supports Super Sampling again, and favors this over Fant when using Best Quality. Fant is still available, but is no longer chosen automatically.

  • Changed: Holding Ctrl when starting to move a selection with the Move Selected Pixels tool will no longer leave behind a copy of the selected area

  • Fixed: Bicubic resampling in the Move Selected Pixels tool was not correctly handling the alpha channel in some cases. This fix has required a reduction in performance.
  • Improved: When using Edit->Copy, a 32-bit BGRA bitmap in the DIBV5 format is now placed onto the clipboard so that other apps can read the alpha channel.

  • Improved: When using Edit->Paste, DIBV5’s are now supported if they have an alpha channel. If they don’t, then the regular DIB loader is used which has some heuristics for detecting an incorrectly defined alpha channel and correcting for it.

  • Improved: When using Edit->Paste, PNG is now the highest priority format. This maximizes the ability to maintain alpha/transparency, but it does mean that images coming from Microsoft Office apps will appear larger than they used to. This is either a bug or a feature of Microsoft Office. For some reason it places PNGs on the clipboard that are 25%+ larger than the DIB/DIBV5 bitmap that it also places on the clipboard (but which don’t have alpha/transparency).

  • Fixed: DIBV5 bitmaps should now work with Edit->Paste, which improves alpha channel handling. (thanks @null54 for the fix!)
  • Fixed: Top-down DIBs should now work correctly with Edit->Paste. (thanks @null54 for the fix!)
  • Improved CPU usage for thumbnail updates (layers and image tabs) in many cases.
  • Improved: Slightly increased the size of the Settings dialog to reduce the need for scrolling in a few important situations
  • Fixed: Simple message boxes can now be closed with the ESC key
  • Fixed: Magic Wand now works on very large images (e.g. 65535 x 65535 pixels) without an error.
  • New: Plugins that use IndirectUI can now use a UriProperty with a LinkLabel control (thanks @null54!)
  • New: Effect plugins can now more easily make use of the clipboard via the IClipboardService. It will handle all of the tricky clipboard issues such as threading, native data marshaling, and avoiding security vulnerabilities that exist in the standard WinForms and WPF clipboard APIs.

  • New: FileType plugins can now specify separate lists of extensions for loading and saving.

  • Blocked the WebP FileType v1.1.0.0 plugin due to instability. An update is already available.
  • Blocked the ImAgif FileType v0.12.0.1084 plugin due to incompatibility. An update will hopefully soon be available.


C#: [Obsolete] on an extension method? Also remove ‘this’

tl;dr – To fully deprecate an extension method when you need to maintain binary compatibility (e.g. plugins), especially if it’s colliding with another extension method, you can simply remove the ‘this’ keyword.

I recently needed to remove a duplicate extension method from the Paint.NET code base. I had two copies of a ServiceProviderExtensions class, one in the PaintDotNet namespace and the other in PaintDotNet.AppModel (which I wanted to remove). They both had a GetService<TService>() extension method:

The second copy was just an absent-minded addition at some point, but of course … some plugins started using the “wrong” one (there’s no way the plugin authors could’ve known). Worse, if you had a using at the top of your C# code file for both namespaces, whether inside the app or out in a plugin, you couldn’t use either of the extension methods because the compiler would give you a “The call is ambiguous between the following methods or properties” error.

Hrumph! So, clearly I wanted to delete one of these. But, how could I do that without breaking plugins? Some were using the first copy, others were using the second copy!

The first solution I came up with was to create a new DLL, let’s call it PaintDotNet.Obsolete.dll. I’d then move the “bad” extension method class into there, add an [assembly: TypeForwardedTo(…)] attribute in the original DLL, and add [Obsolete] onto the methods in the new (err, obsolete) DLL. I couldn’t add [Obsolete] to the class, however, otherwise the TypeForwardedTo attribute would get flagged with an error too. This would mostly work, but was messy and clumsy. I may still need to use this idea in the future to cover other deprecation scenarios.

Finally, it dawned on me: what if I just removed ‘this’ from the extension method signature? This would remove it from IntelliSense, and also remove it as a candidate for extension method resolution at compile time, while still affording binary compatibility with old plugin DLLs.

And … it worked!!!

It works because extension methods and ‘this’ are implemented in the compiler as syntactic sugar. It’s neither a runtime nor a framework feature; once your DLL is compiled, extension methods don’t really exist (at least at the call site).

The ‘this’ keyword turns into an attribute on the method which identifies it as an extension method. When compiling a DLL that consumes the extension method, the code that’s emitted is a normal static method call. Since I wasn’t removing the static method, the old plugin DLLs would still be able to use it.

And thus a years-old conundrum has been solved. Old plugins will continue to work, and new plugins (and new app code!) can use the right extension method without the ambiguity error.

This blog post is based on some tweets I made earlier today: 4.2 beta build 7121 is now available

This should be the last beta before the final release! There isn’t a lot that’s changed, which is a good thing. The most important thing to try out is the application of embedded color profiles. Previously, the color profile was loaded* and then included when saving the image*, but now it is loaded, applied to the image, and discarded (you don’t want to double apply the color profile!). You will probably see some JPEG or HEIC images that now load with more saturated (or possibly less saturated) colors; they will match the appearance you see in Explorer thumbnails and previews.

To get this update, make sure you have "Also check for pre-release (beta) versions" enabled in Settings, and then click on the Check Now button.


You can also download it directly by heading over to the forum.

Changes since 4.2 beta build 7116:

  • New: Embedded color profiles are now applied when loading images of supported file types (JPEG, PNG, HEIC, etc.). This is a one-time conversion to the sRGB color space that results in the color profile being discarded once it has been applied.
  • Fixed: The HEIC file type’s Quality slider is now limited to a maximum value of 90 while Microsoft fixes a heap corruption crash in the codec.
  • Fixed: The DIB and RLE extensions will now be registered for APPX (Store) installations
  • Fixed: Bicubic resampling in the Move Selected Pixels tool was not correctly handling alpha in some cases. This fix has required a reduction in performance.
  • Fixed: Explorer thumbnails for some image types (PDN, DDS, TGA) were not rendering their alpha correctly. You may not see the effect of this fix for a particular image until that image is resaved, or you clear Explorer’s thumbnail cache.

* for supported file types such as JPEG