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

Working with .ICO files #300

Closed
ghost opened this issue May 4, 2020 · 11 comments
Closed

Working with .ICO files #300

ghost opened this issue May 4, 2020 · 11 comments
Labels
fixed (hopefully)

Comments

@ghost
Copy link

ghost commented May 4, 2020

I've been using the latest PhotoDemon nightly for creating transparent Windows icons. It's very good for that, but I still need to save them as PNG files, since saving in ICO format isn't supported. I'd like to suggest that it be supported in future versions.

Thanks!

@ghost
Copy link
Author

ghost commented May 4, 2020

I forgot to mention that I've been converting those PNG files into ICO files with a different imaging program.

@ghost ghost closed this as completed May 4, 2020
@ghost ghost reopened this May 4, 2020
@tannerhelland
Copy link
Owner

Hello @g-busch ! Thank you for this feature request. It is an excellent suggestion.

I have nearly tackled full ICO support in PhotoDemon a few different times over the years, but I did not know if anyone besides me would use it. So I kept putting it off in favor of other tasks.

(Recently I had to do some work on PhotoDemon's application icon, and I ended up using GIMP for the task. I was a little embarrassed that PhotoDemon couldn't do this on its own. 😨 )

Knowing that others could use this feature gives me newfound motivation. Can you let me know a little more about what specific ICO features you need? Are you simply saving a single standalone image as an ICO file?

I ask because ICO files are capable of storing many different embedded icons at different sizes and color-depths. This makes them considerably more complex than e.g. a JPEG or PNG. (In fact, they're more like Photoshop PSD files, with many layers inside a single file.)

If you don't need multi-icon support, I can add basic ICO export over the next few days (time permitting). Full support for multiple embedded icons is a larger task and would take me at least several weeks.

Also, if you don't mind letting me know what other software you've used that handles ICO files well, that is a huge help. It's extremely useful to study other developer's approaches before embarking on my own.

Thanks in advance!

@ghost
Copy link
Author

ghost commented May 7, 2020

Thanks for the response, Tanner. I replied by e-mail, but may have messed up the address, so here it is again:

No, I don't use embedded icons, just standalone .ICO files. One of the apps I've used for that was the Greenfish Icon Editor. It has the added ability to extract icons from .EXE and .DLL files, as well as to change them, although that can corrupt some executables. I even used it in the past to change PhotoDemon's icon. It worked on the nightly builds, but corrupted the stable one. The trouble with the Greenfish editor is its lack of a resize option, and a rather awkward crop function. You have to activate that tool first, then select the area with the mouse. It crops immediately when you let go, and if you don't get it right, you have to start over again, because there's no way of adjusting the selection.

Another application I've used that can create and save .ICO files is an editor called StylePix. I've used that at times, but it lacks some important features, and I don't want to use a whole collection of image editors to carry out tasks that a single image editor could handle on its own. My default image viewer (XnView Classic) can do some basic editing, but the many adjustments in PhotoDemon are far more accurate and flexible than in XnView. For example, XnView's straightening tool doesn't include retaining the aspect ratio when autocropping. It has a sharpening tool, but no unsharp mask, and the color balance controls are very limited.

Before I forget, I really appreciate the inclusion of the cloning tool. Are you planning on adding a healing brush, as well? Not critical, however, as the cloning tool has options that can often produce the same effect.

tannerhelland added a commit that referenced this issue May 11, 2020
Relates to #300.

I've now written a custom ICO importer for PhotoDemon.  It works flawlessly on a random set of icons I've assembled from online sources (and/or created manually), but additional testing from interested parties would be extremely helpful.

The parser handles both old-style uncompressed frames, and modern PNG-compressed frames, at all sizes and color-depths without trouble (in my testing, anyway).  Frame masks are automatically converted to standard alpha channels.  As always, users don't need to understand nuances of how this works - they just get "magic" 32-bpp frames regardless of how an ICO file is constructed.

All frames from a given icon file are loaded automatically and placed into individual layers.  The largest frame is set as the active and only visible layer; all other layers are hidden by default.  This mirrors icon behavior in GIMP and I find it both intuitive and useful when creating application icons.  I am still studying other icon editing software to ensure our behavior matches theirs.

A new engine for exporting icons is up next.  This is more complicated as PD will need to analyze layers to determine proper output settings.  This is less complicated than exporting say PNGs (which have 1000x too many settings to account for) but more complicated than standard single-frame images.  No ETA at present but I hope to have it ready this month.
@tannerhelland
Copy link
Owner

Thank you for the detailed explanation, @g-busch! It's a huge help to know concrete workflow details related to a feature request. I will take a look at the software you mentioned to get a better idea for how PhotoDemon's icon workflow may work.

I am also happy to add you to the contributor list for the next release - just let me know what name and (optional) URL you'd like me to use.

I've just finished work on a homebrew ICO importer for PhotoDemon. The new importer is now available in the latest nightly builds.

I am using this new importer to dissect various ICO files I've found online. The ICO format is so old that many details in the original spec (last updated in 1995!) are no longer valid. Modern icons can be 768x768 or larger (the spec maxes out at 48x48), and embedded icons are no longer just Windows bitmap entries - they can actually be embedded PNG files, too.

The 30+ year history of ICO files has made this one of those features where I just kinda have to study what "everyone else" is doing, and ensure that PhotoDemon follows the same general practices. If any of the icon files you've produced no longer load into PhotoDemon, please let me know so I can get it fixed.

Next, I'm tackling icon exporting. The technical aspects of this are straightforward. As usual, it's the UI that will be difficult. Icons have a bunch of different requirements depending on where/how you intend to use them, so PD needs to provide a straightforward UI for producing many sub-icons in a file from one or more source layers. I don't have a current ETA for getting the export feature up-and-running, but I hope to wrap it up this month (fingers crossed).

I will post here when I have something new to show.

Are you planning on adding a healing brush, as well?

Yes. Someday. :)

Right now my primary effort is getting a new stable release out the door. I was about ready to ship PhotoDemon 8.0 until this icon feature caught my attention. Greatly improved file format support was a big emphasis for this release cycle, and current nightly builds support many new file formats relative to the last stable build (Photoshop PSD, OpenRaster ORA, HEIF, animated PNG and GIF). I've written a ton of import/export code to support all those different formats, so I think it makes sense to fix ICO support too before releasing PhotoDemon 8.0.

Once 8.0 is out the door, a healing brush is high on my to-do list.

@ghost
Copy link
Author

ghost commented May 12, 2020

Well, I haven't encountered a single ICO file that has failed to open in PhotoDemon, and without exception I can also resize them, make changes to the individual objects that are layered over the transparent background, and save the files back in PNG format. XnView converts them to ICOs quickly and easily, so that's what I currently use.

Of course, PhotoDemon loads ICOs containing embedded images as single images, but as I mentioned earlier, that's not important for what I do. What I did notice is this: I loaded an ICO that I know has embedded images into XnView and it came up as a 256x256 image. When I loaded the same file into PhotoDemon, it came up as 48x48. I guess this is conforming to the old original specification, but this happens to be the size I usually use, anyway. Most of my desktop icons are that size, and if they happen to be a bit bigger or smaller, Windows always scales them to fit.

For the contributor list, feel free to use my real name, Gerry Busch. As for my URL, http://gbusch.altervista.org. the site is unrelated to programming or graphic design, as it contains nothing but the scores and MP3s of my music compositions. I know very little about coding, having stopped writing useless little programs in BASIC after the early 90s. The only code I deal with nowadays is for batch files, or the CSS and HTML that I use on my website.

Did that first e-mail reply I sent arrive in the right place? When I went to reply, the address displayed in the To address field was reply+APOLIBANLY4BCAXUPUOAHC54YWJ6FEVBNHHCI6QEMU@reply.github.com, which certainly didn't look right!

@ghost
Copy link
Author

ghost commented May 14, 2020

Just wanted to let you know that I've tested the new icon importer and it works flawlessly. In fact, so does everything else in the latest nightly build.

@ghost
Copy link
Author

ghost commented May 14, 2020

Tanner, on portablefreeware.com I just discovered a tiny program that can convert PNG files to ICO, and embed several image sizes in the process. The program is completely portable, and consists of a standalone EXE less than 400 kb in size. It may give you some ideas for your exporter. The program can be downloaded at https://www.carifred.com/quick_any2ico .

Gerry

tannerhelland added a commit that referenced this issue May 15, 2020
Relates to #300

As usual, this ended up being a much larger and more complicated design project than I anticipated.  Icon files have a huge array of possible export settings (particularly regarding recommended frame sizes and color-depths), and many standalone icon editors have garbage UIs that haven't been updated since the Win 95 era... so they were unfortunately not as helpful as I'd have liked.

(I'm starting to understand why major editors like Photoshop don't export icons at all, instead off-loading the job to 3rd-party plugins!)

Regardless, I've finally arrived at a UI that I think works well.  In keeping with PD's core philosophy of "simple but powerful", the new icon export dialog allows the user to select a target icon purpose from a dropdown (e.g. "Windows 10 app icon").  PD uses that target to auto-populate a large grid of icon frame sizes and color-depths.  This allows you to see what will actually end up inside your icon file.  Users are welcome to toggle on or off any of the size+color options at their leisure.

Note that *ICONS DON'T ACTUALLY EXPORT YET*.  That code is still to-do!  First I needed a UI so I could figure out what export settings I actually need to support, and now I have a solid framework for testing icon export features as I build them.

PD's export feature grid is quite large compared to other software.  I've gone back and forth on how many difference icon frame size + color-depth combinations to support (for example, do I let users write non-square icons?), and the question proved tricky given that one of PD's big use-cases is in legacy Windows environments.  Similarly, VB6 devs are disproportionately likely to use the program, and things like VB6 app icons have special requirements that aren't easily solved using other tools.  I'd like to make sure PD covers those cases.

In the end, I feel like the current UI provides a reasonable trade-off between "OMG this dialog is out of control" and "I can make a perfect icon for my esoteric use-case!"  I ultimately decided to drop support for "technically legitimate but ill-defined" behaviors like non-square icons, because I don't like encouraging file format nonsense that creates potential headaches for other software.  (Also, I don't want to have to build a Windows ME VM just to test what it does with weird icon settings!)

For the "target" applications, I assembled various output settings after (too many) hours of trawling web archive entries of MSDN pages.  Whoever decided to break all legacy MSDN links for the Nth time deserves a swift kick in the groin, because wow it is impossible to find ANYTHING on MSDN these days, especially if it involves documentation written before ~2018.  Aaaaarrgggghhhhh

Enough whining for now.  :)

Thank you again to @g-busch for his ongoing contributions to this feature!  PD's contributor list and Help > About dialog have been updated accordingly
tannerhelland added a commit that referenced this issue May 15, 2020
Relates to #300
Relates to #249

This new tool is straightforward: it takes an image's alpha channel, and converts areas of partial transparency to a pattern of fully opaque and fully transparent "dots".  The tool provides full control over dithering with the same options as other palettize tools, but here, they *only* apply to the alpha channel.

This feature is extremely helpful for ICO and GIF exporting, as it provides a way to mimic partial transparency (e.g drop shadows) using a checkerboard of purely on/off pixels.  This feature was also on my to-do list for implementing #249 properly, as it provides a nice way to support layered images and/or text in a "retro" context.

Also included in this commit is an updated German localization c/o Roy K.  Thank you, Roy!
@tannerhelland
Copy link
Owner

tannerhelland commented May 15, 2020

Thank you for the follow-up info, @g-busch! (And I like your new user icon 👍 )

Of course, PhotoDemon loads ICOs containing embedded images as single images, but as I mentioned earlier, that's not important for what I do. What I did notice is this: I loaded an ICO that I know has embedded images into XnView and it came up as a 256x256 image. When I loaded the same file into PhotoDemon, it came up as 48x48.

Before, PhotoDemon used a 3rd-party library for loading ICO files. By default, only the first frame in an icon file was being retrieved; any others were ignored.

You've probably noticed this already, but PhotoDemon's new homebrew ICO engine loads all embedded icon frames into their own layer(s). By default, the largest + highest-quality frame will be activated; the rest will be added as hidden layers. Layer names describe the size and color-depth of each frame (e.g. 32x32 (8-bpp) means an icon frame is 32 pixels wide by 32 pixels tall, at an original color-depth of 8-bits-per-pixel, or 256 colors).

You can right-click on any layer in the right-hand Layer box, and select Show only this layer to view that icon frame by itself. Similarly, the Image > Fit canvas to active layer command will auto-shrink the image canvas around the currently active layer, if a smaller frame is desired.

Last night I finished up work on an "Export icon" user interface, and this weekend I will start work on the actual code that creates ICO files. Depending on where an icon is meant to be used, many different sizes and color-depths should be embedded in the file. It will take some work to cover all the different combinations, but I'm fortunate to already have most the code available for other file formats. I just need to re-purpose it for ICO-specific rules.

Did that first e-mail reply I sent arrive in the right place?

Unfortunately, I haven't seen it. If it worked, your text would be visible in this thread. GitHub handles all that email interaction on its own, so I'm afraid we're at its mercy.

GitHub account privacy settings can prevent email replies from working (a good thing, actually - threads like this are publicly viewable, and replying to them by email can accidentally reveal email details you'd rather keep secret!). I do feel bad if you lost text due to it, though 😞

Just wanted to let you know that I've tested the new icon importer and it works flawlessly. In fact, so does everything else in the latest nightly build.

Thank you so much for taking a look at it. 👍 I'll reply back here when exporting ICO files is ready for testing.

Tanner, on portablefreeware.com I just discovered a tiny program that can convert PNG files to ICO, and embed several image sizes in the process.

Thank you, I'll take a look!

Best wishes for a happy weekend.

@ghost
Copy link
Author

ghost commented May 15, 2020

No, I didn't lose any of the text from the initial e-mail, as I was able to copy and paste all of it to this thread.

Thanks for the comment on my user icon. It's actually the same one I use on my website, and was created in the Greenfish Icon Editor before I started using PhotoDemon for that purpose.

tannerhelland added a commit that referenced this issue May 21, 2020
Relates to #300

After much work, a new ICO exporter is now available in PD.

All valid ICO color-depths (from 32-bpp PNG through 1-bit monochrome) are supported.  PD can auto-generate as many size and color-depth combinations as you requre.  Just select the corresponding entries from the export UI, or if you're a novice, select a compatibility target (e.g. "Windows 10") and PD will take care of the details for you.

For lower bit-depth frames, optimal palettes and transparency masks are generated automatically.  If your source image contains multiple layers, PD will automatically find the closest-sized layer to each frame to use as its reference.

The export dialog now provides a "use original file settings" option if the current file is already in ICO format.  This makes it trivial to load an ICO file, make changes, then save out an identical set of frames.  Note that while frame sizes and color-depths may be identical, frame order is *not* guaranteed to be identical, by design.  PD automatically sorts frames from highest-quality to lowest-quality to get idealized matching behavior from apps like Windows Explorer.

As usual, I've fully dog-fooded (https://en.wikipedia.org/wiki/Eating_your_own_dog_food) the new ICO exporter.  PhotoDemon's program icon has been re-created using PD's ICO engine.  The new file is 100% identical in terms of pixel contents, but 12% smaller, thanks to PD's (much) more efficient PNG compressor!  (This is one of the best aspects of PD's new ICO engine, IMO - the ability to save space on Vista+ app icons that use PNG frames.)  This is why the resource file was touched by this commit.

Still TODO are a few minor quality enhancements at export-time.  Tiny sizes like 16x16 require special downsampling algorithms to achieve best results.  I need to write my own custom downsampler (instead of "stealing" PD's existing thumbnail engine, as I do at present) which would produce better results at such tiny sizes.  I also need to add full support for dithering colors in 8-bpp, 4-bpp, and 1-bpp color modes (at present, dithering is *not* used when producing those frames).

These changes won't affect the actual ICO format writer  They are just pre-processing steps that improve quality of the final ICO frames.

Once those enhancements are complete, I'll revisit #300 and mark this feature as complete!
@ghost
Copy link
Author

ghost commented May 21, 2020

Great work, Tanner, thanks! I just checked out the latest nightly build, and the export function is working flawlessly, so I no longer need an extra tool to work on icons. The only other graphics program I need now is my default viewer, XnView, but that can be practically any of the myriad viewers out there.

tannerhelland added a commit that referenced this issue May 29, 2020
When matching colors against a palette (via e.g. Effects > Stylize > Palettize), PD can now match colors using the CIE-LAB color space instead of just RGBA.

Simple explanation: this produces visibly better results at a small trade-off to speed.  Long explanation: see wikipedia, https://en.wikipedia.org/wiki/CIELAB_color_space#CIELAB

I will likely switch over PD's file format color-reducers to use the new LAB color matcher, as it can produce better 8-bit images (like GIFs) at no penalty to file size, and with generally reduced need for dithering.  (I've been working on this as part of ICO export; see #300 for details)
tannerhelland added a commit that referenced this issue Jun 8, 2020
Relates to #300

Icon files often require us to aggressively downsize an arbitrary source image.  I've now written a custom downsample strategy specific to ICO frames; this can greatly improve quality when generating small icon frames (16, 32, 48 px) from a much-larger source image.

Source images with non-destructive affine transforms (rotation, etc) are now handled correctly as well.
tannerhelland added a commit that referenced this issue Jun 9, 2020
Relates to #300

When converting a 32-bpp RGBA image to an 8-bpp image (like ICO or GIF), an image's alpha channel needs to be reduced to simple on/off values.  PD supports "alpha dithering" when performing this task, which means it will attempt to mimic complex semi-transparent regions (like drop shadows) using patterns of on/off dots with varying density.  This often produces a "better" result than simply hacking off transparency at a fixed point.

The alpha ditherer now accepts an optional matte color; if none is supplied, white will be used.  (The "matte" color is the assumed background color for semi-transparent pixels.  White is industry standard, but if you expect a different use-case, you can now specify it.)

I've also improved performance when alpha-dithering large images by smarter alpha premultiplication usage.
tannerhelland added a commit that referenced this issue Jun 10, 2020
tannerhelland added a commit that referenced this issue Jun 23, 2020
Relates to #300

Minor alpha dithering modifications for 1- and 4-bit frames to improve output quality at very small sizes, and cleaning up code comments while everything is still (somewhat) fresh in my mind
@tannerhelland
Copy link
Owner

With the PhotoDemon 8.0 beta release now available, I'm content to close this issue. Windows icon (ICO) files are now a first-class citizen in PhotoDemon, with full support for reading and writing icons of any shape or size.

Thank you again to @g-busch for his help! I'm very happy for other users to play with this new feature.

@tannerhelland tannerhelland added fixed (hopefully) and removed in-progress labels Nov 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed (hopefully)
Projects
None yet
Development

No branches or pull requests

1 participant