Hooking modern Windows common dialogs: some notes

Background: common dialog hooking is used to append your own controls to a Windows common dialog box.

A good friend recently sent me a number of resources related to hooking common dialog controls. I’ve been interested in common dialog hooking for PhotoDemon, as it would allow me to add support for image previewing right in the dialog itself. This isn’t as necessary in modern versions of Windows (7 in particular includes a number of GDI+ improvements, making Explorer very robust with standard formats), but it can be helpful for unsupported formats like RAW photographs.

Unfortunately, several days of research have shown that it is not possible to hook a Vista or Windows 7 style dialog and maintain the modern layout. Let me explain with pictures:

This is the standard common dialog control in Windows Vista and 7 (and presumably 8 as well, though I haven't verified this myself).  The biggest improvements over past common dialogs include breadcrumb navigation at the top, a dedicated refresh button, and a persistent search bar.
This is the standard common dialog control in Windows Vista and 7 (and presumably 8 as well, though I haven’t verified this myself). The biggest improvements over past common dialogs include a dedicated left-hand file tree, breadcrumb navigation at the top, and a persistent search bar.

The common dialog above comes directly from PhotoDemon’s current common dialog implementation. This is the native common dialog control on Vista and 7. I very much like it. As a comparison, here is the same dialog in Windows XP:

Same folder as the previous image.  The XP common dialog provides no breadcrumb nav, folder tree, dedicated refresh, or search bar.  Note also how many TIFF formats do not display correctly - including XP not recognizing the MINISWHITE flag on the CCITT TIFF files.  Kinda interesting.
Same folder and images as the previous image. There is no breadcrumb nav, dedicated refresh, or search bar. Note also how many TIFF formats do not display correctly – including XP not recognizing the MINISWHITE flag on the CCITT TIFF files. Kinda interesting.

I strongly prefer the Vista/7-style dialog, particularly the breadcrumb nav and the persistent folder tree on the left.

Unfortunately, it is impossible to hook the Vista/7 dialog and maintain the native Vista/7 appearance. If you attempt to hook it, Windows will ALWAYS drop back to a previous generation common dialog. Here are some images to demonstrate, using a basic image preview hook:

This is what happens when you attempt to hook a dialog, and all you provide is the OFN_ENABLEHOOK flag.  Not pretty (and the hook doesn't even work right).
This is what happens when you attempt to hook a dialog, and all you provide is the OFN_ENABLEHOOK flag. Not pretty (and the hook doesn’t even work correctly).
Here is the same dialog, but with the OFN_EXPLORER flag set.  Note that hooking now works properly, but the common dialog itself has been reduced to XP style - the left-hand folder tree is gone, and the top bar has no breadcrumbs or search.
Here is the same dialog, but with the OFN_EXPLORER flag set. Note that hooking now works properly, but the common dialog itself has been reduced to XP style – the left-hand folder tree is gone, and the top bar has no breadcrumbs or search.

Note that the image above uses an older version of the OPENFILENAME struct, namely (this is its declaration in VB):

Private Type OPENFILENAME
    lStructSize       As Long
    hwndOwner         As Long
    hInstance         As Long
    lpstrFilter       As String
    lpstrCustomFilter As String
    nMaxCustFilter    As Long
    nFilterIndex      As Long
    lpstrFile         As String
    nMaxFile          As Long
    lpstrFileTitle    As String
    nMaxFileTitle     As Long
    lpstrInitialDir   As String
    lpstrTitle        As String
    Flags             As Long
    nFileOffset       As Integer
    nFileExtension    As Integer
    lpstrDefExt       As String
    lCustData         As Long
    lpfnHook          As Long
    lpTemplateName    As String
End Type

If you modify the struct to its newest version (as described here), you can slightly improve the dialog to look like this:

The newest version of the OPENFILENAME struct enables the places bar on the left.  I don't find this particularly useful - certainly not as useful as a folder pane - but perhaps some might find it preferable.
The newest version of the OPENFILENAME struct enables the places bar on the left. I don’t find this particularly useful – certainly not as useful as a folder pane – but perhaps some might find it preferable.

That is the best you can get if you want to hook a common dialog in Vista or 7.

Reasons for this have been speculated on by more qualified individuals than I. Over at stackoverflow, David H explains:

The reason for this is that MS completely re-organised the file dialogs for Vista. Hooks are used to extend a file dialog by supplying a resource file. This gives the customiser too much power. They can all too easily modify standard elements of the dialog and indeed many apps did so. The reorganisation of the dialogs would have broken many apps that used hooks. Those would have tried to manipulate elements of the dialog that were not there, or were implemented differently. Legacy versions of the dialogs remain for such apps to “get their hooks into”.

You are correct that it is impossible to get the new look when you use a hook. Instead you need to use the IFileDialogCustomize interface to customise the dialog. This is less powerful but does result in appearance and behaviour that is more consistent with the standard part of the dialog.

(More information is available here for those who are interested.)

Unfortunately, I am not aware of any way to access the iFileDialogCustomize interface in classic VB. If someone knows how, I’d love to hear it.

The take home message of all this is – if you work in classic VB and you want to hook a common dialog, you need to be content with an XP-style dialog. There is currently no way to maintain a Vista/7 style dialog while hooking.

For this reason, I’m going to stick with the stock common dialog control in PhotoDemon. I may look at a dedicated “browse” window in the future, which would allow for full image previewing, but I’m afraid such a feature is not on the roadmap for the next few versions.

All hooking-related screenshots were created using Carles PV’s iBMP project, which made it very easy to modify various hooking parameters and test the output. Thanks, Carles!

Announcing PhotoDemon 5.2 – Selections, HSL, Rotation, HDR, and More

Summary

PhotoDemon v5.2 is now available. New features include selection tools, arbitrary rotation, HSL adjustments, CMYK support, new user preferences, multiple monitor support, and more. Download the update here.

PhotoDemon 5.2
Version 5.2 includes many new tools and features, including PhotoDemon’s first on-canvas tool – “Selections”.

New Feature: Selection Tool

Selections have been one of the top-requested PhotoDemon features since it first released, so I’m glad to finally be able to offer them. A lot of work went into making selections as user-friendly and powerful as possible.

Three render modes are provided. On-canvas resizing and moving are fully supported, as are adjustments by textbox (see screenshot above). Everything in the Color and Filter menus will operate on a selection if available, as well as the Edit -> Copy command.

(Note: as of this v5.2, selections are not yet tied into Undo/Redo, and selections will not be recorded as part of a Macro. These features will be added in the next release.)

New Feature: Crop to Selection

Finally!

New Feature: HSL Adjustments

PhotoShop and GIMP users should be happy about this tool.

New Feature: Arbitrary (Free) Rotation

Arbitrary rotation comes courtesy of the FreeImage library. A 3-shear method is used: very fast, very high quality.

New Feature: CMY/K Rechanneling

Both CMY and CMYK rechanneling are now available.

New Feature: Sepia (W3C formula)

Here’s the sepia version of the photo from the Rechannel screenshot. I still prefer PhotoDemon’s “Antique” filter for most photos, but this sepia formula (from the W3C spec) provides a pleasant, flat alternative.

New Feature: Preferences Dialog (rewritten from scratch)

Preferences, preferences, and more preferences. The old Preferences dialog was pretty lame, so it was due for an overhaul. Tons of new settings have been added, and they are now organized by category.

New preferences include:

Interface:

  • Render drop shadows between images and canvas (similar to Paint.NET)
  • Full or compact file paths for image windows and Recent File shortcuts
  • Improved font rendering on Vista, Windows 7, and Windows 8 (via Segoe UI)
  • Remember the main window’s location between sessions

Loading and Saving:

  • Tone map imported HDR and RAW images
  • Options for importing all frames or pages of multi-image files (animated GIFs, multipage TIFFs)

Tools:

  • Automatically clear selections after “Crop to Selection” is used

Transparency handling:

  • Pick your own transparency checkerboard colors
  • Pick from three transparency checkerboard sizes (4×4, 8×8, 16×16)
  • Allow PhotoDemon to automatically remove empty alpha channels from imported images

All preferences from v5.0 remain present, and there is now an option to reset all preferences to their default state – so experiment away!

New Feature: Recent File Previews (Vista, Windows 7, Windows 8 only)

Now that recent file previews are available, I honestly can’t use any software that *doesn’t* provide the feature. It makes locating the right file significantly easier – especially with digital camera filenames like IMG_0366.jpg.

New Feature: Multi-Image File Support (animated GIFs, multipage TIFFs)

PhotoDemon will now recognize when you try to load image files that are actually composed of multiple images. You are given the option to import every image, or just the first one (which is what most other software does). The default behavior can be changed in the Edit -> Preferences menu.

New Feature: Waaaay better transparency handling, including adding/removing alpha channels

It’s hard to overstate how much better transparency support is in v5.2 compared to v5.0. Images with alpha-channels are now rendered as alpha in all viewport, filter, and tool screens. When printing, saving as 24bpp, or copying to the clipboard, transparent images are automatically composited against a white background. As mentioned previously, user preferences have been added for transparency checkerboard color and sizes.

PhotoDemon also allows you to add or remove alpha channels entirely. Here’s an example of an image with an alpha channel, and the associated “Image Mode” setting:

Note how the top-level “Mode” icon has changed to match the current mode – this saves you from having to go to the sub-menu to check. I’m a big fan of small touches like this.

And here it is again, after clicking the “Mode -> Photo (RGB | 24bpp | no transparency)” option:

No more alpha!

Finally, PhotoDemon now validates all incoming alpha channels. If an image has a blank or irrelevant alpha channel, PhotoDemon will automatically remove it for you. This frees up RAM, improves performance, and leads to a much smaller file size upon saving. (Note: this feature can be disabled from the Edit -> Preferences menu if you want to maintain blank alpha channels for some reason.)

New Feature: Custom “Confirm Unsaved Image(s)” Prompt

This is the new “unsaved images” prompt in PhotoDemon. A preview is now provided – again, very important for digital photos with obscure names – and the options have been reworked to make them as crystal-clear as possible. Also handy is the “Repeat this action for all unsaved images” option, which will either save or not save all unsaved images per your request.

Improved Feature: Edge Detection

Edge detection now allows for on-black or on-white processing. Generally speaking, on-white is used for artistic purposes, while on-black is used for technical and research ones. (Thanks to Yvonne Strahovski, who appears in the sample image above.)

New Feature: Thermograph Filter

This Wikipedia article describes thermography in great detail. PhotoDemon’s thermography filter works by correlating luminance with heat, and analyzing the image accordingly. Here’s a sample, using a picture of the lovely Alison Brie, of Mad Men and Community fame:

New Feature: JPEG 2000 (JP2/J2K), Industrial Light and Magic (EXR), High-Dynamic Range (HDR) and Digital Fax (G3) image support

PhotoDemon now supports importing the four image types mentioned above, and it also supports JPEG 2000 exporting.

Other New and Improved Features:

  • Much faster resize operations, thanks to an updated FreeImage library (v3.15.4)
  • Multiple monitor support during screen captures (File -> Import -> Screen Capture)
  • Many miscellaneous interface improvements, including generally larger command buttons, text boxes, labels, and more uniform form layouts.
  • Many new and improved menu icons.
  • Heavily optimized viewport rendering. PhotoDemon now uses a triple-buffer rendering pipeline to speed up actions like zooming, scrolling, and using on-canvas tools like the new Selection Tool. Even when working with 32bpp images, all actions render in real-time.
  • Bilinear interpolation is now used during Isometric Conversion. This results in a much higher-quality transform. Hard edges are still left along the image border to make mask generation easy for game designers.
  • Vastly improved image previewing when importing from VB binary files.
  • Better text validation throughout the software. Invalid values are now handled much more elegantly.
  • More accelerator hotkey support, including changes to match Windows standards (such as Ctrl+Y for Redo, instead of the previous Ctrl+Alt+Z).
  • Update checks are now performed every ten days (instead of every time the program is run).
  • All extra program data – including plugins, preferences, saved filters and macros – have been moved to a single /Data subfolder. If you run PhotoDemon on your desktop, this should make things much cleaner for you.
  • PhotoDemon’s current and max memory usage is now displayed in the Preferences -> Advanced panel.
  • Tons of miscellaneous bug fixes, tweaks, and optimizations. For a full list of changes, visit https://github.com/tannerhelland/PhotoDemon/commits/master

In Conclusion…

Not bad for two months work, eh? I hope you enjoy all the new features in 5.2., and please remember to donate if you find the software useful!

Announcing PhotoDemon 5.2 Beta 1 – Testers Needed!

PhotoDemon 5.2 beta 1 screenshot
It’s time for another PhotoDemon update. This update includes many new tools, including PhotoDemon’s first on-canvas tool – “Selections”.
  1. Summary
  2. Download
  3. List of what’s new and improved

Summary

PhotoDemon 5.2 is nearing completion, and I need help testing it. Version 5.2 provides a bunch of new features, including selections, cropping, HSL adjustment, CMY/CMYK rechanneling, a new Sepia filter (based off the W3C standard), an overhauled preferences engine and interface, and more. Please download the beta and help me make sure everything is working properly.

Download

The PhotoDemon 5.2 beta comes in two flavors:

Remember – if you are an advanced user, you can always download the most recent development build of PhotoDemon’s source code from its GitHub page.

PhotoDemon is funded by donations from users like you.
Please consider a small donation to fund development and to help me support my family.
Even $1.00 helps. Thank you!

List of what’s new and improved in v5.2 (so far)

  • Selection tool! It’s a hell of a tool, and a lot of work went into making it as user-friendly and powerful as possible. Three render modes are provided. On-canvas resizing and moving are fully supported as well. Everything in the Color and Filter menus will operate on a selection if available, as well as the Edit -> Copy command. (Note: as of this beta, selections are not yet tied into Undo/Redo, and selections will not be recorded as part of a Macro.)
  • PhotoDemon Selection Tool
    Here’s an example of the selection tool in action. Note that the HSL adjustment tool is only operating on the selected area.
  • Image cropping is now possible via the Crop-to-Selection option (in the Image menu).
  • New HSL adjustment tool. (See above screenshot for sample.)
  • New Rechannel tool. Live previews, CMY, and CMYK color spaces were added.
  • PhotoDemon’s new and improved Rechannel tool.
  • New Sepia filter based off the official W3C formula (available here). I still prefer PhotoDemon’s “Filters -> Antique” effect, but felt it was worthwhile to make both available.
  • Here’s the sepia version of the photo from the Rechannel screenshot. I took this photo during a hike up Spanish Fork Canyon several weeks ago; the fall colors were stunning.
  • Vast improvements to PhotoDemon’s support for images with transparency. Images with alpha-channels will now be rendered as alpha in all filter and tool screens. When printing, saving as 24bpp, or copying to the clipboard, the image will be composited against a white background. User preferences were also added for transparency checkerboard color and sizes.
  • All-new User Preferences dialog. Many new options were added, and the Preferences interface is now sorted by category.
  • Interface-related options in the new Preferences dialog.
    As another example, here are the afore-mentioned transparency handling options.
  • Improved font rendering is now available for users on Windows Vista, Windows 7, and Windows 8.
  • A drop-shadow can now be rendered between the image and the canvas (similar to Paint.NET).
  • PhotoDemon is now capable of remembering its window size and position between sessions.
  • Multiple monitors are now supported by the Import -> Screen Capture tool.
  • Many miscellaneous interface improvements. Additionally, I am testing a new layout in the Color -> Grayscale tool. This layout style is intended to help users make sense of PhotoDemon’s many options. Let me know what you think, because if this style is popular, I will redo the other tool dialogs to match.
  • Heavily optimized viewport rendering. PhotoDemon now uses a triple-buffer rendering pipeline to speed up actions like zooming, scrolling, and using on-canvas tools like the new Selection Tool. Even when working with 32bpp images, all actions should render in real-time on any modern system.
  • Bilinear interpolation is now used in “Convert to Isometric Image”. This results in a much higher-quality transform. Hard edges are still left along the image border to make mask generation easy for game designers.
  • Many bug fixes and miscellaneous improvements. For complete details, please visit the commit log at https://github.com/tannerhelland/PhotoDemon/commits/master

My grandfather, Fritz Helland, was found last night. (Updated 1 November 2012)

Update on 1 November 2012

Last night, two hikers located my grandfather’s body. It was found at the bottom of a steep incline some 1.5 miles up Neff’s Canyon. His dog, Odin, was also found with him. The official report from the Medical Examiner will take some time to process, but it looks like the initial fall probably claimed both lives.

This news is difficult, but my family is so grateful to have some closure. Thank you again to all the heroes who helped us resolve this difficult situation – especially the detectives, police officers, firefighters, and community volunteers. A “Missing” poster of my grandfather was placed at the head of the trail where his body was found, and without that who knows if he would have been found before the winter snow hits.

Fritz was a kind, peaceful, brave and brilliant man. He will be dearly missed.

Original Article

It has been a difficult week.

On Wednesday, 24 October 2012, my aunt stopped by Grandpa Helland’s home for a weekly visit. Grandpa wasn’t home, so my aunt called to make sure he was okay. He answered the phone call and said that he was on his way home, and he gave his location as Skyline High School which is only two blocks from his home. He was on a walk with his dog Odin, a miniature Doberman Pinscher, and there was no indication that anything was wrong.

That was the last time anyone heard from him.

Fritz Helland is 80 years old, 5’10”, and of slight build (165 lbs). He has white hair, blue eyes, and a distinctive Norwegian accent. He has now been missing for six days.
Since that time, a massive search and rescue operation has been launched. Helicopters, bloodhounds, and more than 200 police officers and firefighters were dispatched on Friday night. On Saturday morning, a volunteer effort was mounted. Hundreds of community volunteers joined in the search. The search intensified on Sunday as many local churches canceled services, instead directing church members to join in the search.

By Sunday night, 17 square miles of Salt Lake City had been searched, including everything from I-80 to 5200 south, and from 1300 East to the benches, including Millcreek Canyon. Nearly two thousand volunteers participated in the official police-led search groups, while hundreds more searched informally.

On Monday, volunteer search efforts were called off. Due to the bitterly cold temperatures from Wednesday to Friday, and the length of time that grandpa has been missing, the efforts are now focused on finding his body. Cadaver dogs have been dispatched to high probability areas.

To summarize, here is what we know:

  • Fritz Helland is 80 years old. He is 5’10” and of thin build, maybe 165 lbs. He has white hair, blue eyes, and a distinctive Norwegian accent. He was last seen wearing a tan jacket.
  • Fritz was last seen with his dog, Odin, a miniature Doberman Pinscher. Odin has a black coat, with brown markings on his snout, chest, the inside of his ears, and his legs. Odin is also missing.
  • Two very likely sightings of Fritz and his dog occurred on Wednesday around 11:00a.m. These sightings occurred not far from his home (the location was 2700 east and 3500 south, specifically). Fritz appeared to be making his way east, toward home.
  • At 3:00 on Wednesday afternoon, Fritz’s daughter stopped by his home with dinner for the night. Fritz wasn’t there. His daughter called his cell phone, and Fritz answered. He told her he was walking past Skyline High School (which is roughly two blocks southeast of his home). There was no sign of anything being wrong. His daughter had to leave, but she left dinner for him on the kitchen table. This dinner was never touched, which along with other factors, makes it unlikely that Fritz ever made it home on Wednesday.
  • Fritz’s wallet, car keys, and vehicle were found at home. As far as we know, the only belongings he had with him at the time of his disappearance were his cell phone and the clothes on his back. (The dog was also with him.)
  • Cell phone records show that a tower near the high school handled the aforementioned phone call. This is not conclusive evidence of Fritz’s location, as he could be within several miles of that tower – but it does mean that at the time of the phone call, he was no more than five miles from home.
  • All subsequent phone calls have gone straight to voicemail, and the phone’s battery has since died. No better fix could be made on the location.
  • Regarding Fritz’s state of mind, he does have some issues with short-term memory – as would be expected of a typical 80-year-old male – but he is coherent, and to our knowledge he has never had an episode that would explain a disappearance like this. Additionally, his dog has been with him for 16 years and they have walked in the area every day during that time. It is unlikely that both he and the dog would not be able to find their way home.
  • From Friday, October 26th, to today (October 30th), the combined efforts of bloodhounds, helicopter and infrared, specialized search teams, and volunteer efforts have turned up no evidence of Fritz or his dog. Police efforts continue but organized community search efforts have been suspended.
  • Due to the snowstorm and bitterly cold temperatures on the evening of Fritz’s disappearance, a possible scenario is that he and the dog may have become disoriented and sought shelter – perhaps in a shed, a trailer, an abandoned home, or somewhere else out of the public eye. At this time, police are asking residents of Salt Lake City to search their sheds, trailers, and yards for any sign of Fritz or his dog. Cadaver dogs have also been dispatched to high priority areas to assist in this search.
  • If you know anything that may help us locate Fritz, please contact the Unified Police Department at 801-743-7000.

A number of sites have been assembled to help coordinate search efforts. These include:

If you have any relevant information to share, please share it with the police at 801-743-7000. Please do not send tips to me or other family members, as we will only direct you to the official police contact.

If you do not live in the Salt Lake City area, please still keep an eye out. The forceable abduction of an adult male and his dog would be extremely rare, but at this point we are not ruling anything out. Again, please report any possible sightings to the police at 801-743-7000.

Anything you can do to help spread the word is also appreciated. Facebook, Twitter, blogs, email – the venue doesn’t matter. The more people looking for grandpa, especially in the Salt Lake area, the better our chances of finding him.

My family and I are so incredibly grateful for the police and fire department’s efforts, especially that of Sheriff Winder and Detective Faulkner, as well as the overwhelming help from community volunteers. Thank you from the bottom of our hearts.

(I will do my best to update this page if more information becomes available.)

Announcing PhotoDemon 5.0 – Everything is Faster, Everything is Better

Summary

PhotoDemon v5.0 is now available. It’s the biggest update PhotoDemon has seen in years, and it’s awesome. Download it here.

PhotoDemon 5.0 boasts a ton of improvements – both on the surface and under the hood.

New Feature: All-New Image Subsystem

In version 5.0, the way PhotoDemon stores and processes image data has been rewritten from scratch. What does this mean for you?

  • Filters, effects, and all tools are faster than version 4.4.
  • The software uses roughly half the RAM of previous versions.
  • No more upper limit on image sizes. Huge photos (30+ megapixel) should work just fine on any modern PC. The only limiting factor is the amount of RAM (actual and virtual) available on your system.
  • Much faster batch conversions. As an example of how much better version 5.0 is: I ran two identical batch conversions of 138 wedding photos (10 megapixels each, 3872×2592 pixels). The batch conversion was simple – load each image, then save it in another folder at a different JPEG quality. PhotoDemon 4.4 performed the conversion in 2 minutes 21 seconds. PhotoDemon 5.0 does it in 1 minute 11 seconds.
  • Much better OSX and Linux compatibility via Wine. (Wine v1.4 or later is required.)

This sole feature was the largest update PhotoDemon has seen in the past five years. As a teaser, the new subsystem is also compatible with selections and layers, which may make an appearance in a future update…

New Feature: Alpha-Channel (Transparency) Support

For the first time in the history of the program, PhotoDemon now provides proper transparency support. When images with an alpha-channel are loaded, PhotoDemon will automatically maintain the transparency data for the life of the image. When the image is saved to file, the alpha-channel is added back in, allowing you to do any amount of edits to images without harming the underlying alpha data.

Transformations like resizing and rotating also preserve the alpha channel. (Again, this was a prerequisite to features like layers… see a pattern here?)

New Feature: Redesigned Interface

Every menu item in PhotoDemon now has a descriptive icon, and menus have been reorganized according to improved design rules. No menu is more than two layers deep, and new accelerators (hotkeys) have been added to popular features.

The redesigned Color menu

The left-hand bar has been updated once again. Per feedback from users, a dedicated Close and Save As button has been added, along with descriptive text for each button. Tool-tips have also been added to each button. (Thanks to Robert Rayment for the suggestion!) Finally, the zoom box has been rebuilt with a new, more useful set of zoom values.

New left-hand bar in 5.0, including descriptive tool-tips.

All preview boxes have been enlarged on tool, filter, and effect windows. Text has also been enlarged to improve readability. PhotoDemon was originally designed to run on 800×600 resolutions (that was a concern in 2001!) but there’s no need for it to remain so compact in 2012.

The old and new edge detection tools
The old and new Custom Filter tools

Finally, a new View menu has been added to provide compatibility with other popular photo editors. The new menu is a great place to discover all the useful hotkeys (also called “accelerators”) for popular zoom functions. The key listed on the right-hand side of a menu item can be used as a shortcut to that menu – so pressing the “+” key will zoom in, the “-” key will zoom out, and the “0” key will instantly fit the entire image on the screen.

The new View menu

New Feature: All-New Image Load/Save Engine

PhotoDemon 5.0 uses a completely new system for getting images into – and out of – the program. As you may know, the program relies on an outside library called FreeImage for supporting non-standard image formats like Photoshop files (PSD), Macintosh PICT files (PICT), DirectDraw surfaces (DDS), and more.

FreeImage is an excellent tool, but its implementation in past versions of PhotoDemon was very rudimentary. PhotoDemon relied on FreeImage to do its own image file type detection, configure each image type properly, and prepare it for use within the program. While it was pretty good at guessing these parameters, it was not foolproof, and odd color-depths, transparencies, and mismatched file extensions could result in failed image loads or even program crashes.

So for version 5.0, the FreeImage interface was rewritten from the ground up. When images are loaded, a fallback system is used to identify the file format – first the file header is compared against a database of known filetypes. That works for 95+% of files. If for some reason a header cannot be found (which is the case with some formats, including outliers like CUT, MNG, PCD, TGA and WBMP), the image’s file extension is then analyzed. If that fails, PhotoDemon will attempt to blindly load bitmap data and hope for the best. And, if even that fails, PhotoDemon will give the image one final try by passing control off to the Windows’ GDI+ system and seeing if it can decipher the file.

This should make PhotoDemon as robust as possible when loading images. (Thanks to Herman Liu for much testing and help with the new image import implementation!) The full list of file formats supported by PhotoDemon now includes:

Importing:

  • BMP – Windows Bitmap
  • DDS – DirectDraw Surface
  • GIF – Compuserve
  • ICO – Windows Icon
  • IFF – Amiga Interchange Format
  • JNG – JPEG Network Graphics
  • JPG/JPEG – Joint Photographic Experts Group
  • KOA/KOALA – Commodore 64
  • LBM – Deluxe Paint
  • MNG – Multiple Network Graphics
  • PBM – Portable Bitmap
  • PCD – Kodak PhotoCD
  • PCX – Zsoft Paintbrush (uncompressed only)
  • PDI – PhotoDemon Image (the program’s native format)
  • PGM – Portable Greymap
  • PIC/PICT – Macintosh Picture
  • PNG – Portable Network Graphic
  • PPM – Portable Pixmap
  • PSD – Adobe Photoshop
  • RAS – Sun Raster File
  • SGI/RGB/BW – Silicon Graphics Image
  • TGA – Truevision Targa
  • TIF/TIFF – Tagged Image File Format
  • WBMP – Wireless Bitmap

Exporting:

  • BMP – Windows Bitmap
  • GIF – Graphics Interchange Format
  • JPG – Joint Photographic Experts Group
  • PDI – PhotoDemon Image (the program’s native format)
  • PNG – Portable Network Graphic
  • PPM – Portable Pixel Map
  • TGA – Truevision Targa
  • TIFF – Tagged Image File Format

New Feature: Color Temperature Tool

A full discussion of color temperature and how it works is available at this Wikipedia article, but a simple description is: color temperature allows you to retroactively adjust the lighting of a photograph. It’s a powerful way to change the mood of a photo, or to adjust lighting to reflect how you remember a scene – versus what the camera actually caught.

The all-new Color Temperature tool. To my knowledge, no other free photo editor provides a tool like this.

I’m quite proud of this tool, in part because it took a ridiculous amount of work to build. Other free photo editors like GIMP and Paint.NET lack anything like this, so short of Photoshop, PhotoDemon is one of the only software programs to provide such a feature.

The image below – a promotional poster for the HBO series True Blood – nicely demonstrates the potential of color temperature adjustments. On the left is the original shot; on the right, a color temperature adjustment using PhotoDemon. In one click, a nighttime scene can been recast in daylight.

Color temperature adjustment in action.

New Feature: Black and White (1-bit) Conversion

PhotoDemon already possesses a powerful grayscale engine, with more conversion options than any other tool on the market. But what if you want to literally convert an image to black and white – as in just black and just white?

Now you can, thanks to a revamped black-and-white tool.

The new black-and-white tool, rewritten from scratch for 5.0.

The new tool operates hand-in-hand with a flexible, powerful dithering engine. The new engine design allows for any combination of dithering and threshold, and if you’d like, you can also have PhotoDemon estimate an ideal threshold value for a given image. (An ideal threshold is one that leads to an image that’s roughly 50% black and 50% white.)

A comprehensive assortment of dithering algorithms is provided, including: Bayer 4×4 and 8×8, False (fast) Floyd-Steinberg, Genuine Floyd-Steinberg, Jarvis/Judice/Ninke, Stucki, Burkes, Sierra-3, Two-Row Sierra, Sierra Lite, and my personal favorite – Bill Atkinson’s classic Macintosh algorithm, which featured prominently in the original Apple Macintosh. Images treated with this algorithm evoke a certain nostalgia for anyone old enough to remember that era of computing.

Atkinson dithering, as applied to a screen capture from a Warehouse 13 episode.

New Feature: Tile Tool

Have you ever needed to tile an image? There are a lot of ways to do it. Most involve copying-and-pasting an image over and over again, then manually arranging those copies into a grid.

I hate tedious tasks like that. So PhotoDemon has a new tool that makes tiling a trivial operation.

The new Tile tool.

You can tile according to three rules: the current screen size (automatically detected), a set size in pixels, or a set number of tiles. The tool will automatically convert between each system for you, and it will let you know the size of the final image in both tiles and pixels.

Other new features and updates in version 5.0

Other updates in v5.0 include:

  • New “Duplicate Image” tool. Perfect for making a working copy of an image without fear of overwriting the original. (Thanks to Achmad Junus for the suggestion!)
  • Drag-and-Drop compatibility. Drag images from your desktop or file manager onto PhotoDemon, and it will open them all automatically. (Thanks to Kroc of camendesign.com for the suggestion!)
  • Auto-Enhance overhaul. All four auto-enhance tools (contrast, highlights, midtones, shadows) have been rewritten from scratch using completely new algorithms. I think you’ll find them way more useful than the old tools.
  • Improved mosaic tool. Faster, higher quality, and mosaics can now be as large as the image or as tiny as one pixel in either dimension.
  • Improved handling of edge pixels for all convolution filters (blur, soften, sharpen, etc)
  • Improved manual color reduction algorithms (faster and higher quality)
  • New histogram equalization form. Equalize any combination of color channels (red, green, blue) and luminance with real-time previews.
  • DPI-aware images mean no more distortion at 120dpi – a big improvement for people using “large font” settings.
  • Fixes for users of the “Classic Theme” in modern versions of Windows. Your menus should look much better in this release.
  • Improved bug reporting system and online form to match.
  • Tons of miscellaneous bug fixes, tweaks, and optimizations. For a full list of changes, visit https://github.com/tannerhelland/PhotoDemon/commits/master

In Conclusion…

I hope you enjoy the many improvements in version 5.0. As always, feel free to contact me with any feedback you might have.

How to Convert Temperature (K) to RGB: Algorithm and Sample Code

Converting temperature (Kelvin) to RGB: an overview

If you don’t know what “color temperature” is, start here.

While working on a “Color Temperature” tool for PhotoDemon, I spent an evening trying to track down a simple, straightforward algorithm for converting between temperature (in Kelvin) and RGB values. This seemed like an easy algorithm to find, since many photo editors provide tools for correcting an image’s color temperature in post-production, and every modern camera – including smartphones – provides a way to adjust white balance based on the lighting conditions of a shot.

Example of a camera white balance screen. Image courtesy of http://digitalcamerareviews2011online.blogspot.com

Little did I know, but it’s pretty much impossible to find a reliable temperature to RGB conversion formula. Granted, there are some algorithms out there, but most work by converting temperature to the XYZ color space, to which you could add your own RGB transformation after the fact. Such algorithms seem to be based off AR Robertson’s method, one implementation of which is here, while another is here.

Unfortunately, that approach isn’t really a mathematical formula – it’s just glorified look-up table interpolation. That might be a reasonable solution under certain circumstances, but when you factor in the additional XYZ -> RGB transformation required, it’s just too slow and overwrought for simple real-time color temperature adjustment.

So I wrote my own algorithm, and it works pretty damn well. Here’s how I did it.

Caveats for using this algorithm

Caveat 1: my algorithm provides a high-quality approximation, but it’s not accurate enough for serious scientific use. It’s designed primarily for photo manipulation – so don’t try and use it for astronomy or medical imaging.

Caveat 2: due to its relative simplicity, this algorithm is fast enough to work in real-time on reasonably sized images (I tested it on 12 megapixel shots), but for best results you should apply mathematical optimizations specific to your programming language. I’m presenting it here without math optimizations so as to not over-complicate it.

Caveat 3: this algorithm is only designed to be used between 1000 K and 40000 K, which is a nice spectrum for photography. (Actually, it’s way larger than most photographic situations will ever call for.) While it will work for temperatures outside these ranges, the estimation quality will decline.

Special thanks to Mitchell Charity

First off, I owe a big debt of gratitude to the source data I used to generate these algorithms – Mitchell Charity’s raw blackbody datafile at http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html. Charity provides two datasets, and my algorithm uses the CIE 1964 10-degree color matching function. A discussion of the CIE 1931 2-degree CMF with Judd Vos corrections versus the 1964 10-degree set is way beyond the scope of this article, but you can start here for a more comprehensive analysis if you’re so inclined.

The Algorithm: sample output

Here’s the output of the algorithm from 1000 K to 40000 K:

Output of my algorithm from 1000 K to 40000 K. The white point occurs at 6500-6600 K, which is perfect for photo manipulation purposes on a modern LCD monitor.

Here’s a more detailed shot of the algorithm in the interesting photographic range, which is 1500 K to 15000 K:

Same algorithm, but from 1500 K to 15000 K

As you can see, banding is minimal – which is a big improvement over the aforementioned look-up table methods. The algorithm also does a great job of preserving the slightly yellow cast leading up to the white point, which is important for imitating daylight in post-production photo manipulation.

How I arrived at this algorithm

My first step in reverse-engineering a reliable formula was to plot Charity’s original blackbody values. You can download my whole worksheet here in LibreOffice / OpenOffice .ods format (430kb).

Here’s how the data looks when plotted:

Mitchell Charity’s original Temperature (K) to RGB (sRGB) data, plotted in LibreOffice Calc. Again, these are based off the CIE 1964 10-degree CMFs. The white point, as desired, occurs between 6500 K and 6600 K (the peak on the left-hand side of the chart). (Source: http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html)

From this, it’s easy to note that there are a few floors and ceilings that make our algorithm easier. Specifically:

  • Red values below 6600 K are always 255
  • Blue values below 2000 K are always 0
  • Blue values above 6500 K are always 255

It’s also important to note that for purposes of fitting a curve to the data, green is best treated as two separate curves – one for temperatures below 6600 K, and a separate one for temperatures above that point.

From here, I separated the data (without the “always 0” and “always 255” segments) into individual color components. In a perfect world, a curve could then be fitted to each set of points, but unfortunately it wasn’t that simple. Because there’s a large disparity between the X and Y values in the plot – the x-values are all over 1000, and they are plotted in 100 point segments, while the y values all fall between 255 and 0 – it was necessary to transpose the x data in order to get a better fit. For optimization purposes, I stuck to first dividing the x value (the temperature) by 100 across each color, followed by an additional subtraction if it led to a significantly better fit. Here are the resultant charts for each curve, along with the best-fit curve and corresponding R-squared value:

Apologies for the horrifically poor font kerning and hinting in those charts. I love LibreOffice for many things, but its inability to do font aliasing on charts is downright shameful. I also don’t like having to extract charts from screenshots because they don’t have an export option, but that’s a rant best saved for some other day.

As you can see, the curves all fit reasonably well, with R-square values above .987. I could have spent more time really tweaking the curves, but for purposes of photo manipulation these are plenty close enough. No layperson is going to be able to tell that the curves don’t exactly fit raw idealized blackbody observations, right?

The algorithm

Using that data, here’s the algorithm, in all its glory.

First, pseudocode:



    Start with a temperature, in Kelvin, somewhere between 1000 and 40000.  (Other values may work,
     but I can't make any promises about the quality of the algorithm's estimates above 40000 K.)
    Note also that the temperature and color variables need to be declared as floating-point.

    Set Temperature = Temperature \ 100
    
    Calculate Red:

    If Temperature <= 66 Then
        Red = 255
    Else
        Red = Temperature - 60
        Red = 329.698727446 * (Red ^ -0.1332047592)
        If Red < 0 Then Red = 0
        If Red > 255 Then Red = 255
    End If
    
    Calculate Green:

    If Temperature <= 66 Then
        Green = Temperature
        Green = 99.4708025861 * Ln(Green) - 161.1195681661
        If Green < 0 Then Green = 0
        If Green > 255 Then Green = 255
    Else
        Green = Temperature - 60
        Green = 288.1221695283 * (Green ^ -0.0755148492)
        If Green < 0 Then Green = 0
        If Green > 255 Then Green = 255
    End If
    
    Calculate Blue:

    If Temperature >= 66 Then
        Blue = 255
    Else

        If Temperature <= 19 Then
            Blue = 0
        Else
            Blue = Temperature - 10
            Blue = 138.5177312231 * Ln(Blue) - 305.0447927307
            If Blue < 0 Then Blue = 0
            If Blue > 255 Then Blue = 255
        End If

    End If

In the pseudocode above, note that Ln() means natural logarithm. Note also that you can omit the “If color < 0” checks if you will only ever supply temperatures in the recommended range. (You still need to leave the “If color > 255” checks, though.)

As for actual code, here’s the exact Visual Basic function I’m using in PhotoDemon. It’s not yet optimized (for example, the logarithms would be much faster via look-up table) but at least the code is short and readable:


'Given a temperature (in Kelvin), estimate an RGB equivalent
Private Sub getRGBfromTemperature(ByRef r As Long, ByRef g As Long, ByRef b As Long, ByVal tmpKelvin As Long)

    Static tmpCalc As Double

    'Temperature must fall between 1000 and 40000 degrees
    If tmpKelvin < 1000 Then tmpKelvin = 1000
    If tmpKelvin > 40000 Then tmpKelvin = 40000
    
    'All calculations require tmpKelvin \ 100, so only do the conversion once
    tmpKelvin = tmpKelvin \ 100
    
    'Calculate each color in turn
    
    'First: red
    If tmpKelvin <= 66 Then
        r = 255
    Else
        'Note: the R-squared value for this approximation is .988
        tmpCalc = tmpKelvin - 60
        tmpCalc = 329.698727446 * (tmpCalc ^ -0.1332047592)
        r = tmpCalc
        If r < 0 Then r = 0
        If r > 255 Then r = 255
    End If
    
    'Second: green
    If tmpKelvin <= 66 Then
        'Note: the R-squared value for this approximation is .996
        tmpCalc = tmpKelvin
        tmpCalc = 99.4708025861 * Log(tmpCalc) - 161.1195681661
        g = tmpCalc
        If g < 0 Then g = 0
        If g > 255 Then g = 255
    Else
        'Note: the R-squared value for this approximation is .987
        tmpCalc = tmpKelvin - 60
        tmpCalc = 288.1221695283 * (tmpCalc ^ -0.0755148492)
        g = tmpCalc
        If g < 0 Then g = 0
        If g > 255 Then g = 255
    End If
    
    'Third: blue
    If tmpKelvin >= 66 Then
        b = 255
    ElseIf tmpKelvin <= 19 Then
        b = 0
    Else
        'Note: the R-squared value for this approximation is .998
        tmpCalc = tmpKelvin - 10
        tmpCalc = 138.5177312231 * Log(tmpCalc) - 305.0447927307
        
        b = tmpCalc
        If b < 0 Then b = 0
        If b > 255 Then b = 255
    End If
    
End Sub

This function was used to generate the sample output near the start of this article, so I can guarantee that it works.

Sample images

Here’s a great example of what color temperature adjustments can do. The image below – a promotional poster for the HBO series True Blood – nicely demonstrates the potential of color temperature adjustments. On the left is the original shot; on the right, a color temperature adjustment using the code above. In one click, a nighttime scene can been recast in daylight.

Color temperature adjustments in action. (Click for full size)

The actual color temperature tool in my PhotoDemon project looks like this:

PhotoDemon’s Color Temperature tool.

Download it here to see it in action.

addendum October 2014

Renaud Bédard has put together a great online demonstration of this algorithm. Check it out here, and thanks to Renaud for sharing!

addendum April 2015

Thank you to everyone who has suggested improvements to the original algorithm. I know there are a lot of comments on this article, but they’re worth reading if you’re planning on implementing your own version.

I’d like to call out two specific improvements. First, Neil B has helpfully provided a better version of the original curve-fitting functions, which results in slightly modified temperature coefficients. His excellent article describes the changes in detail.

Next, Francis Loch has added some comments and sample images below, which are very helpful if you want to apply these corrections to a photograph. His modifications produce a much more detailed image, as his sample images demonstrate.

Announcing PhotoDemon 5.0 Beta 1 – Testers Needed!

  1. Summary
  2. Download
  3. PhotoDemon 5.0: A Bit of Background
  4. List of what’s new and improved
PhotoDemon’s biggest update in years is nearing completion, which means it’s time for you to try and break it. Give it a spin and let me know what you think of the improvements (which are many!)

Summary

PhotoDemon 5.0 is nearing completion, and I need help testing it. Version 5.0 includes an all-new image subsystem that required rewriting every filter and effect in the program (and some 17,000 lines of code!). All those changes have made the software significantly faster and smoother, but it might also have broken a few things. Download the beta and help me make sure everything is working the way it’s supposed to.

Download

The PhotoDemon 5.0 beta 1 comes in two flavors:

Remember – if you are an advanced user, you can always download the most recent development build of PhotoDemon’s source code from its GitHub page.

PhotoDemon is funded by donations from users like you.
Please consider a small donation to fund development and to help me support my family.
Even $1.00 helps. Thank you!

PhotoDemon 5.0: A Bit of Background

As you might know, PhotoDemon has a long and complicated history spanning some 12 years. That longevity has some perks – for example, tons of features – but it also has some downsides.

One of the biggest downsides to being 12 years old is that the software carries with it some bad design choices, made many years ago when I was a young and immature programmer, that have perpetually bogged down the implementation of new and exciting features. In particular, features like large images, selections, and alpha-channel (transparency) support have all been impossible because of the way PhotoDemon stores and renders images. Originally, the software was only meant to work on 8-bit images, and 24-bit support was later tacked on as an afterthought. I took that framework as far as I could go, but upon releasing PhotoDemon to the public earlier this year, I realized that it was time to fix that problem.

Enter version 5.0.

PhotoDemon 5.0 has just about been rewritten from the ground up, and I don’t say that lightly. The software is comprised of some 30,000 lines of code, and version 5.0 involved the writing of more than half (17,000) of those lines. Why? Because it was finally time for a completely new image subsystem, one capable of potentially supporting selections, alpha-channels, high bit-depths, layers, and whatever else I might want to someday throw at it.

(Note: features like selections are not yet part of PhotoDemon. They will take a good chunk of time to write – but at least now it will be physically possible to add them!)

This new image subsystem is something I’m very proud of. At a high level, it’s basically a specialized image class that stores and tracks all image data, and passes that data between the screen, image files, and various filters and effects. The subsystem does not rely on anything specific to Visual Basic (the programming language PhotoDemon is written in), meaning it is capable of supporting any features it wants – regardless of whether or not VB actually supports them. Past versions of PhotoDemon relied on VB’s inherent “picture boxes”, as they are called, for image storage and processing, and because VB6 is now 14 years old it simply couldn’t handle things like large images or transparency.

But no more.

This rewrite has been a massive project, and every single filter and tool (every damn one!) had to be rewritten to accommodate the new technology. This proved to be a good thing, because I hadn’t revisited some of those filters for over a decade, and in the past ten years I’ve learned a great deal about writing cleaner, better, faster imaging code. That made this a prime chance to re-engineer every filter and tool in the program to make it as fast and accurate as possible, and I think you’ll like the result.

But enough about this – you probably want to know what’s actually new in PhotoDemon 5.0. I won’t discuss everything here (some features are still under construction), but here are the highlights.

List of what’s new and improved in v5.0 beta 1

  • Everything is faster – all filters, tools, effects, loading images, saving images, macros, batch conversion, undo/redo. Seriously – EVERYTHING.
  • Completely rewritten image load/save code. As an example of how much better the new version is: I ran two identical batch conversions of 138 wedding photos (10 megapixels each, 3872×2592 pixels). The batch conversion was simple – load each image, then save it in another folder at a different JPEG quality. PhotoDemon 4.4 did the conversion in 2 minutes 21 seconds. The PhotoDemon 5.0 beta did it in 1 minute 11 seconds. (Thanks to Herman Liu for much testing and help with the implementation!)
  • Redesigned menus. Every item has a descriptive icon, and menus have been reorganized according to improved design rules
  • Menus now have useful icons and improved organization
  • Drag-and-Drop compatibility. Drag images from your desktop or file manager onto PhotoDemon, and it will open them all automatically. (Thanks to Kroc of camendesign.com for the suggestion!)
  • MUCH better Wine compatibility for OSX and Linux users. Undo/Redo and all tools and effects should now work under Wine. Let me know if you find any that do not.
  • New “Tile” tool tiles the current image to a target size (in pixels) or number of tiles. (Thanks to Ye Peng for the suggestion!)
  • PhotoDemon’s new “Tile” tool
  • New “Duplicate Image” tool. Perfect for making a working copy of an image without fear of overwriting the original. (Thanks to Achmad Junus for the suggestion!)
  • Auto-Enhance overhaul. All four auto-enhance tools (contrast, highlights, midtones, shadows) have been rewritten from scratch using completely new algorithms. I think you’ll find them way more useful than the old tools.
  • Improved mosaic tool. Faster, higher quality, and mosaics can now be as large as the image or as tiny as one pixel in either dimension.
  • Added previewing to a bunch of forms that lacked it before – Reduce Colors (Quantize), Black and White Conversion, Find Edges
  • Increased size of all preview windows. They are now much larger, which makes it easier to see how a filter or tool will affect an image.
  • Improved handling of edge pixels for all convolution filters (blur, soften, sharpen, etc)
  • Improved color reduction algorithms (faster and higher quality)
  • Floating-point implementation of histogram equalization means it is now significantly more accurate
  • DPI-aware images mean no more distortion at 120dpi – a big improvement for people using “larger font” settings in Windows
  • No limit on image sizes. The bigger, the better. (Thanks to Robert Rayment for his help with this bug!)
  • Full GDI+ support for saving and loading. If the FreeImage plugin can’t be found, GIF/JPEG/PNG/TIFF import and export will still be available. (Thanks to Alfred Hellmueller for the suggestion to add GDI+ compatibility!)
  • Turbo JPEG loading while batch conversions are running
  • Improved bug reporting system and online form to match
  • Tons of miscellaneous bug fixes, tweaks, and optimizations

Announcing PhotoDemon 4.4 – Now With Update Notifications, Improved Histogram, and More

Summary

PhotoDemon v4.4 is now available. It has a lot of cool new features. Download it here.

New Feature: Update Notifications

The most important update in version 4.4 is the addition of an automatic update notifier.

PhotoDemon's new update notifier
PhotoDemon’s new update notifier.

By default, PhotoDemon will check for updates whenever the software is run. Automatic update checks can be disabled from the Edit -> Preferences menu. You can also manually check for updates by going to Help -> Check for Updates.

I’m not sold on the layout of the update notification form – particularly the center alignment of the version numbers, which looks off due to the white space on the right-hand side – so its appearance may change in future versions, but at least this first draft conveys all the essential information.

Finally, note that this is merely an update notifier, not an automatic updater – clicking the “Yes” button will only open the PhotoDemon download page in your browser. It will not download the update for you, and it will not overwrite your current copy of the software. This is my preferred behavior for portable applications, but I am open to suggestions for better methods.

New Feature: Helpful Undo/Redo Text

The left-hand bar in v4.4 has been redesigned from version 4.3:

Comparison of v4.3 and v4.4 left-hand bar
v4.3 is on the left, v4.4 is on the right

The new, more compact version is in preparation for adding additional tools to the bottom section of the left-hand bar. It was also done as part of the new “friendly text” version of the Undo/Redo buttons:

new Undo/Redo interface
PhotoDemon’s helpful new Undo/Redo text.

I tried displaying the full text of the Undo/Redo action in the Undo/Redo buttons themselves, but as some of the descriptions are rather long, the button text would get pushed onto multiple lines (or off the button entirely!) making them look terrible. So the current implementation is: hover over the Undo/Redo button to see what action will be performed. As you can see, the Edit menu also contains a full-text description of Undo/Redo behavior.

Redesigned Histogram

With version 4.4, I don’t think it’s biased to say that PhotoDemon provides the best image histogram tool in the business:

PhotoDemon 4.4's redesigned histogram
PhotoDemon 4.4’s redesigned histogram

Individual channels can now be hidden or displayed in any combination. (The histogram will automatically adjust its maximum and minimum values accordingly.) This is useful for comparing just two color channels, for example, or comparing a single color channel against luminance.

The histogram now provides a “use smooth lines” option. This enables two features: antialiased lines (which VB does not do natively, so it’s a custom implementation), and cubic spline interpolation. Here’s an example of the aesthetic difference this makes:

Comparison of histogram render methods
Makes a difference, doesn’t it?

The new histogram interface provides a logarithmic rendering option. Images that are very dark or very bright will blow out the histogram at one end or the other, making it very difficult to see what’s happening in those ranges. Take the histogram of this beautiful FF7 fan art from pixiv.net user マップ, for example:

Image in need of a logarithmic histogram

Logarithmic histogram in action

Classic features like displaying the values of the histogram level under the cursor are still present, and you can still export the histogram image to an 8-bit PNG, GIF, or BMP file.

Finally, as of version 4.4 PhotoDemon’s histogram window is now non-modal. This means that you can leave the histogram window open while loading/saving/manipulating images, and the window will automatically refresh itself when necessary. Perform a filter or color operation and the histogram will update to reflect those changes; Undo a previous action and it will also update, making it very useful for comparing the effects of various filters.

As part of these updates, the histogram code has been newly refactored and optimized, so it’s fast and extremely low-resource, even when left open during image operations. All histogram data is pre-calculated, so when you change rendering options (such as enabling/disabling channels or switching between logarithmic and regular representation) the new histogram is instantly redrawn without requiring a recalculation of the raw data.

I’m not done with histogram updates, but v4.4 provides a great improvement over v4.3.

Redesigned Grayscale Interface and New Grayscale Algorithms

The grayscale conversion form has been completely redesigned in v4.4:

Redesigned grayscale interface
Special thanks to pixiv user ぴよな*ティア for the image in the preview.

Grayscale conversion was one of the last features to lack an instant-preview option, but no longer – you can now see real-time previews of the various grayscale algorithms.

I have also ported over all seven of the grayscale conversion algorithms from my standalone grayscale project, some of which were not present in PhotoDemon. The full list of available grayscale conversion methods now includes:

  • Averaging
  • ITU standard (adjusting for cone density in the human eyes)
  • Desaturation (HSL color space)
  • Decomposition to maximum or minimum values
  • Single color channel reduction
  • Reduction to specific # of gray shades
  • Reduction to specific # of gray shades with dithering

PhotoDemon defaults to the ITU standard method, which is the best choice for people who have no idea what these various options mean. :) For a full discussion of how these methods work and why some are preferable to others, see my aforementioned in-depth grayscale article.

Finally, the reduce-to-specific-number-of-shades option can now be used to reduce an image to black and white (two shades). Previously it required three shades or more. That said, I still advise using PhotoDemon’s specific “convert to black and white” menu option, which provides more control over 2-color reduction.

Other miscellaneous updates and bugfixes

Other updates in v4.4 include:

  • The system hand cursor is now automatically applied to all clickable objects. This was previously done manually, and because VB isn’t smart about sharing resources, a hand cursor was stored in multiple places throughout the .exe. The new automated feature meant I could remove those references, so the new v4.4 .exe is actually smaller than v4.3, despite including a bunch of additional features. Windows Vista/7 users will also get a much prettier hand icon.
  • Batch conversion now has a more robust error handler. This is in preparation for the addition of an all-new batch conversion wizard, which didn’t make the cut for 4.4 but should be included in 4.5
  • Miscellaneous bug fixes related to save prompting, MDI maximizing, and more. See a full list of updates at PhotoDemon’s commit page on github.

In Conclusion…

I hope you enjoy the changes in version 4.4. As always, feel free to contact me with any feedback you might have.

Where does Microsoft make money? (Updated 2012)

THIS INFORMATION IS OUTDATED. Click here to see the updated 2013 report.

As in past years, all information in this report is taken from Microsoft’s publicly available 2012 10-K filing. Numbers may vary from past reports. When Microsoft moves products between revenue categories, they retroactively adjust the totals for past years so that year-to-year comparisons are accurate. This article uses 2010 and 2011 values as calculated in the 2012 report. All values are in USD.

If you’ve read my past reports, feel free to skip down to the charts. If this is your first time here, let me provide a quick explanation of how Microsoft breaks down its earnings.

Microsoft Total Revenue and Operating Income (June 2011 – June 2012)

Total Revenue: $73,723,000,000
Operating Income: $21,763,000,000

Total Revenue is the total amount of money Microsoft takes in from normal business operations.

Operating Income is calculated as (Operating Revenue – Operating Expenses). In other words, “Operating Income” is the profit made from normal business operations. (A more formal definition is available from Investopedia: “Operating income would not include items such as investments in other firms, taxes or interest expenses. In addition, nonrecurring items such as cash paid for a lawsuit settlement are often not included. Operating income is required to calculate operating margin, which describes a company’s operating efficiency.”)

Operating Income is particularly important when looking at a company like Microsoft. Certain Microsoft divisions take in a great deal of money, but they also require much higher costs to operate. Therefore, it is important to look at not just how much money a certain division brings in – but at how much it costs to operate that division.

Microsoft total revenue and operating income, 2010 - 2012
Long story short: Microsoft’s 2012 revenues were up over 2011, but operating income fell.

Microsoft Revenue and Operating Income by Division (June 2011 – 2012)

Microsoft products (and earnings) are divided into five divisions: Windows & Windows Live, Microsoft Business, Server and Tools, Entertainment and Devices, and Online Services. The types of products and services provided by each segment are summarized below:

  • Windows and Windows Live – Windows operating system, Windows Live applications and web services, Microsoft PC hardware products.
  • Microsoft Business – Microsoft Office (including Office Web Apps and Office 365), Microsoft Exchange, Microsoft SharePoint, Microsoft Lync, Microsoft Office Project and Office Visio, and Microsoft Dynamics ERP and CRM.
  • Server and Tools – Windows Server operating system, Windows Azure, Microsoft SQL Server, SQL Azure, Visual Studio, Silverlight, Windows Intune, Windows Embedded, System Center products, Microsoft Consulting Services, and Premier product support services.
  • Entertainment and Devices – Xbox 360 console, games, and accessories (e.g. Kinect), Xbox LIVE, Windows Phone. In 2012, Microsoft also added Skype to this division.
  • Online Services – Bing, Microsoft adCenter, MSN, and Atlas online tools for advertisers.

(Note: these divisions are pretty much identical to 2011, with the exception of Skype being added to Entertainment and Devices.)

Here are the 2011-2012 revenue and operating income values for each division, in USD. Note that the number in parentheses is the percentage change between 2011 and 2012.

Windows and Windows Live
Revenue: $18,373,000,000 (-3%)
Operating Income: $11,460,000,000 (-6%)

Business (Office, Exchange, SharePoint)
Revenue: $23,991,000,000 (+7%)
Operating income: $15,719,000,000 (+7%)

Server and Tools (Windows Server, Microsoft SQL, Visual Studio)
Revenue: $18,686,000,000 (+12%)
Operating Income: $7,431,000,000 (+18%)

Entertainment and Devices (XBox 360/LIVE, Windows Phone)
Revenue: $9,593,000,000 (+8%)
Operating income: $364,000,000 (-71%)

Online Services (Bing, MSN, Hotmail)
Revenue: $2,867,000,000 (+10%)
Operating income: $-8,121,000,000 (*)

(* – Microsoft marks the large difference between Online Services’ 2011 and 2012 operating income as “not meaningful.” The explanation: “OSD’s fiscal year 2012 operating loss reflects a goodwill impairment charge of $6.2 billion, which we recorded as a result of our annual goodwill impairment test in the fourth quarter. The non-cash, non-tax-deductible charge related mainly to goodwill acquired through our 2007 acquisition of aQuantive, Inc.”)


Total Revenue Charts – 2012

Microsoft revenue by division 2012 (raw values)
Microsoft total revenue by division in 2012. (Amounts in millions USD.)

 

Microsoft revenue by division 2012 (percentages)
Microsoft total revenue by division for 2012, as percentages. Note that in terms of pure revenue, Microsoft Business outperforms every other division. This chart is also nice for showing just how little XBox, Bing and – at present – Windows Phone matter to Microsoft’s current cash flow. That may change in the future, but for now it is all about Office, Windows, and Server/Tools.

Operating Income Chart – 2012

Microsoft operating income by division 2012
Microsoft operating income, by division, for 2012. (Amounts in millions USD.) Note that Online Services represents an $8.1 billion dollar LOSS. Microsoft Business is far and away the most profitable division, while Server and Tools – which brought in as much revenue as the Windows division in 2012 – represents significantly less profit. Again, note how insignificant XBox and Windows Phone are from a profit standpoint.

Year-over-year comparisons (2010-2012)

Microsoft revenue by division (2010-2012)
Microsoft revenue by division for the years 2010, 2011, and 2012. Overall revenue continues to trend upward, despite Windows sales falling for two years straight. It will be very interesting to see how the October launch of Windows 8 affects next year’s numbers.

 

Microsoft operating income by division (2010-2012)
Microsoft operating income by division for the years 2010, 2011, and 2012. Unlike revenue, operating income varies dramatically from year to year. Microsoft Business dominated profits in 2012, while Online Services continued to hemorrhage a frightening amount of money. Entertainment and Devices also took a huge hit from 2011, so don’t be surprised if Microsoft becomes increasingly aggressive about improving profitability of XBox and Windows Phone in 2012.

Announcing PhotoDemon: A Fast, Free, Open-Source Photo Editor and Image Processor

PhotoDemon screenshot
PhotoDemon v4.2 in the midst of a massive batch conversion (1643 files)

tl;dr – I’ve spent 12 years working on an advanced image processing program. (Think PhotoShop, but without any on-canvas painting tools.) The software is now available under the title “PhotoDemon.” It is fast, free, completely open-source (BSD licensed), and it provides a number of useful features, including macro recording and automated batch conversion. You can download it here.

I can’t often say that a blog post has been 12 years in the making… but believe it or not, this post has taken me that long to write.

Many years ago, when I was but a lowly high school student, I legitimately believed that I alone could produce the world’s greatest video game. It was going to be epic in every possible way – immersive 3D graphics, fully orchestrated musical score, hundreds of pages of witty dialogue. I was going to program the whole thing myself in Visual Basic 6.0, and it was going to be AWESOME.

(ROFL)

This might shock you, but that game never came to fruition.

Fortunately, my delusional teenage aspirations weren’t entirely a waste – I did end up writing many hours of original music for the game, and I also produced a suite of useful development tools. One of those tools was called the GenesisX Image Studio, after my one-man GenesisX Production Company. (Yes, that name sounded cool to my teenage mind.) The purpose of GenesisX Image Studio was to convert 24-bit image files to the game’s custom 8-bit Genesis X Format.

Perhaps you recall, but back in the year 2000 bandwidth was hard to come by, and distributing a game chock full of large 24-bit images over the Internet simply wasn’t feasible. GIF images were still under patent protection so there were concerns about using them, and PNG wasn’t widely known or supported. So I decided to write my own image format, and this was the program capable of converting JPEGs and BMPs to that:

GXF Compressor screenshot
Here’s a screenshot of the GenesisX Image Studio. I know – it burns the eyes a little. Don’t you love the red/black gradient? It seemed so edgy at the time. (facepalm)

While the GXF Compressor was hideous to look at, it included some interesting code, including a rather clever interactive palette editor. That palette editor was at the heart of the Genesis X Format. It worked by taking 256-color images and blending low-frequency colors at a ratio of their occurrences within the image. This way, it was possible to get a 256-color image down to 128 colors or less with very little degradation; the image would then be RLE compressed and optionally zLib compressed, and it was capable of producing downright tiny files.

GXF Palette Editor
The GenesisX Palette Editor. I’m not sure why I felt the need to plaster a bright red copyright message on the form… I’m fairly certain no one was interested in stealing my painfully amateurish code.

When the ultimate game project associated with this software died, I continued to peck away at the image studio, mostly because I enjoyed learning about image processing and the software already provided a framework for things like loading and saving images, zooming and scrolling them, and a rudimentary set of filters. Over time, I eliminated the 256-color feature set and focused only on 16 million color support. Eventually the ridiculous “GenesisX” moniker was dropped, and the project was renamed “DemonSpectre Image Workshop.” (DemonSpectre was my online alias at the time.)

DemonSpectre Image Workshop
By 2002, the project had become slightly less hideous. The red/black gradient was replaced by the blue/black gradient made famous by InstallShield, and a thoroughly useless logo was added to the left-hand side. The code base also grew to include a variety of new filters and processing techniques.

In 2002, Microsoft introduced the first version of Visual Studio .NET, effectively obsoleting the COM-based VB6 overnight. I was in university by then, and had become very aware that VB was not the right language for a programmer who wanted to be taken seriously in the U.S. job market. So I learned C++, java, and Perl, though I retained a love for classic VB, in large part because it was the language that got me into programming in the first place.

The next 8-9 years saw slow, incremental upgrades to the software, usually the result of a random night or weekend when I was fed up with work and needed to focus on something not-work-related. Eventually I renamed the software “VB Photoshop” (no copyright problems there!), then later PhotoDemon, a mash-up of my old DemonSpectre moniker and the fact that the software had grown to focus primarily on photo editing.

In fact, my interest in digital photography led to many of the program’s best features, since I used PhotoDemon to implement tools that other image editing programs lacked or implemented poorly. (I’m looking at you, PhotoShop batch conversion!) Since its inception, PhotoDemon also served as a testbed for my image processing work in other programming languages, because for all its flaws, classic VB is unbeatable as a rapid prototyping language. I still use it for first-implementation tests of obscure features or filters, simply because I can go from pseudocode to real-time implementation in minutes (versus hours in java, and days/months in C). And because VB6 compiles down to native code (unlike the interpreted P-code of earlier versions), it’s perfect for prototyping image processing code, which often needs to execute in real-time.

PhotoDemon v4.2 menu screenshot
PhotoDemon has come a long way from its original GenesisX Image Studio roots. The current version looks quite nice, and it includes features I find lacking in other software – such as extensive accelerator (“hotkey”) support. For those who don’t utilize accelerators, the menus are designed to maximize discoverability. IMO they’re a significant improvement over most image editing software menus.

Because I continued to receive a surprising amount of traffic to my VB-oriented programming site, I would periodically strip interesting features out of PhotoDemon and publish them independently. In fact, most of my open-source programming projects are merely subsets of PhotoDemon’s codebase. (And it’s a surprisingly large codebase – over 30,000 lines – and that’s not including the 3rd-party DLLs it relies on for extra functionality.)

Every now and then, I’ll receive an email from a poor programmer who’s stuck supporting a legacy VB6 application and has consequently stumbled across my site. These emails always brighten my day, and they’re the reason I still provide VB6 projects despite the language being “dead” for more than 10 years. (Although “dead” is a relative term – Microsoft’s extended support lasted until 2008, and they have promised “it just works” compatibility for VB6 applications FOR THE LIFETIME of Windows 8. I know people have their criticisms of Microsoft, but no major tech company is half as good as they are when it comes to supporting legacy software. Hats off to Microsoft for that.)

Occasionally, these emails will ask me if I have a single project that condenses my many image processing techniques into a single piece of software. For ten years, my response to this question has been a vague, teasing, “maybe I do – you’ll have to wait and see!” I’m not sure why I’ve never just tell people about PhotoDemon… probably because they would pester me for copies of the code, and I hate sending out .zip files of large source directories, especially when I haven’t made up my mind about how I want to license said code.

But this summer, as I was sending out yet another one of these vague email responses, it struck me that I’d spent the past ten years hinting at PhotoDemon but never really thinking seriously about when it might live somewhere besides my hard drive. Wasn’t it time to seriously commit to getting the project in a workable state? (Anyone who knows me shouldn’t find this surprising – my motto has always been “better late than never,” and boy does this project meet that definition!)

So I committed, then and there, to getting PhotoDemon into a workable state. My last three months have been spent cleaning up its code base, stripping out useless functions and features, writing documentation, and coaxing it to work with modern Windows visual styles – no small feat, considering VB6 never worked with Windows XP visual styles, let alone Windows 7.

PhotoDemon current version screen shot
PhotoDemon, as it looks in August 2012. Note the use of Windows 7 visual styles, along with full MDI support. Also – no hideous background gradient! :)

Because I’m a glutton for punishment, I also got PhotoDemon working with modern version control software. (Here it is on GitHub.) I wonder if I’m the first person to try and get a massive VB6 codebase working properly with Git… Surprisingly, it does work, though it takes some tweaking thanks to VB’s strange intermixing of text and binary files. Maybe someday I’ll document what I did. Then again, maybe not – I’m not sure I want people trying to set up legacy VB projects with GitHub, lol.

After getting the code to a pleasantly robust state, I put up a preliminary project page for PhotoDemon on this site. That was six weeks ago. Thus far it seems to have been well-received among the VB programmers who frequent my site, and with the help of those programmers, many miscellaneous bugs have been squashed. After a rigorous few weeks of testing, I think PhotoDemon is finally stable enough to warrant broader use.

And that’s why this blog post exists.

Over the next few weeks, possibly months, I plan on releasing a series of “developer diaries” that discuss PhotoDemon’s features and design in detail. I don’t know many projects with a 12-year development time that spans from the developer first learning to program to becoming a professional coder, and I think my experiences could be useful for other young programmers looking to embark on their own open source project. Also, some of PhotoDemon’s more advanced capabilities – such as macro recording and playback – represent unique design challenges, and I think it could be worthwhile to discuss the implementation hurdles I faced in hopes of helping other programmers build such features right on their first try.

PhotoDemon v4.2 print dialog
PhotoDemon’s current interface aims to find that sweet spot between minimalism and power. For example, here’s the print dialog. I find most print dialogs to be woefully over-engineered, so this one provides only the options I use on a regular basis. Also, I just noticed that the “Orientation” label is misaligned vertically. D’oh! Better go fix that…

But for now, here’s what’s worth mentioning: PhotoDemon is stable, and I’d love your feedback on it. It’s designed as a portable app, meaning no installer is required. Just download the .zip, extract it, and run PhotoDemon.exe. (Not a Windows user? PhotoDemon should work with the latest stable release of Wine.)

Input is welcome from programmers and non-programmers alike. To download just the executable, use this link:

Download PhotoDemon (software only, no source code)

If you want the program AND its complete source code, download it from PhotoDemon’s GitHub page:

Download PhotoDemon (with complete source code)

A GitHub account is not required. Simply click the “ZIP” button with the cloud-and-arrow icon to download the source in standard VB6 format. (The ZIP button is just below the project description, in the top-left quadrant of the page.)

Issues can be submitted from the “Help” menu within PhotoDemon, or by visiting the Issues page, or by simply sending me an email.

Stay tuned for posts describing PhotoDemon’s (quite large) feature set in detail, as well as in-depth guides for its advanced features, including macro recording and batch conversion.

Finally, note that PhotoDemon is updated regularly. I tend to make commits on at least a weekly basis, and often more frequently than that. For the most up-to-date version of the software, download it from GitHub.

Thanks for your interest, and I hope you enjoy the software.