When is a jpeg not a jpeg?

Answer: when it’s in the resources folder of a Xojo build.

In which case it sheds its jpeggie cocoon and takes flight as a full-fledged png. Feedback 64728 reports “it’s not a bug. It’s a feature.”

Has this behavior been discussed before? In my case it is adding 100 megabytes to some otherwise unexceptional executables.

We commonly have clients complaining that a JPEG doesn’t open, because they have a PNG, BMP or GIF renamed with jpeg file extensions.
Most image viewers don’t care, but if you use our classes, they may only handle one type.

I’m assuming you’re dragging the image into the project? If you have a build step move the images into resources yourself, they will stay intact.

Still, it’s an odd choice to always export as PNG and JPEG both have their places, and one isn’t inherently better than the other. Most concerning is the color space. PNG only supports 24-bit color, while JPEG can do 32-bit. So converting a JPEG to PNG has the potential for data loss. And as you’ve seen, they compress differently too. JPEG allows lossy compression, thus the smaller sizes. Converting to PNG doesn’t magically get that quality back. So I find it a very odd decision by Xojo to convert images without permission. Only the author can decide which format is best.


Maybe the choices were made having transparency in account, as JPEG besides being a lossy format is opaque too. But as you said, having the choice is the best way. I think that the system could handle it using PNG at design time to guarantee the lossless feature during the lifetime of the project but when compiling it, if requested, OPTIONALLY, the image put in the resources folder could be the source PNG converted to a JPEG one using some preset options. Logically, those images set to this mode, will lose the alpha channel e become opaque and need to have some color set as a background default for such areas.

This looked promising but did not work for me in a quick trial. I may be missing some nuance. And it feels like I would now own the problem of picking HiDPI or not.

As always with “It does what??!?” oddities like this one, it would be helpful to hear from Xojo. At the IDE level, a jpeg is a jpeg and reports as such when double-clicked in an image set. But come build time, it is explicitly changed to a png. What is the thinking?

It is fine to say that there was a complexity with jpegs at build time, the simple solution was to convert to png, and the team has bigger fish to fry. Then we’d know and can move on.

1 Like

How do you get the images into Xojo? I have a simple copy step script that does images where I don’t need HiDPI. And yes, if you want the pics HiDPI then you need to make them so. As far as I remember this was discussed recently.

IIRC, the reason it does this is that the different platforms have varying levels of support for the different image formats that are available on each platform. macOS is by far the most forgiving, but PNG is guaranteed to support transparency and to always be RGBA, whereas JPEG comes in several flavors (including JPEG2000) and could also be CMYK, which our framework doesn’t handle very well. PNG also does not carry any of the licensing issues that has plagued JPEG over the years.

FWIW, If you are concerned about maintaining the original formats, you could just load them at runtime like we do in the IDE, although that’s not why we do it.


Thank you very much, Greg, for the background. It’s always good to know that things are how they are for a reason (or six) and I am wholly dependent on Xojo for Mac Windows interoperability. Please never waver on that.

1 Like

Okay. Doing things at run time seems to hold promise. I can zip up my jpg’s and put the resulting .zip into the resources folder at build time. Then, at run time, I can unzip into the applications support area and use the images from there. Jpg’s stay jpg’s and my built executables shrink dramatically. Now I have to sort out how to know whether to use the 1x or the 2x version of each image. Most of the forum posts on hidpi detection are old and all are confusing.

Just add them to a Picture then use BestRepresentation:

Var p as New Picture( 100, 100, Array(myPictureAt1X, myPictureAt2X, myPictureAt3X) )
g.DrawPicture( p.BestRepresentation( 100, 100, ScaleFactor ), X, Y )

A bit more to it than that, but that should get you started.

Thank you Anthony for the pointers. After a long weekend of what we used to call SMOP (“Small Matter of Programming”) I have made progress and am getting clean @2x images from a build that has shrunk by a factor of four. I still need to test on an old non-retina system.

1 Like

And not all jpeg’s are created equal. I forget what vendor it is but we had to use MBS plugins to properly read it. Our use case is NOT normal since we don’t know where the data is coming from so we have to try several variations to read graphics formats. And we also have to support the use case where it might have jpg extension but might really be something else. So much fun.

1 Like

Changing the file extension is a speciality of some users :frowning:

And those users do not know what a file extension is.

And some other users unzip rar files (go figure)…

Well, and it’s often used for nefarious purposes to screw up monitoring software.

1 Like

My sense is that all images are put through the png meat grinder at build time, probably including valid pngs that are converted into themselves. That way the compiler has a clean playing field, even if the resulting resource folder is immense.

Makes sense to me. File size isn’t an issue nowadays, and most of us aren’t building 10 megapixel jpegs into our apps that require more than what’s supported in a standard PNG.

As a final reckoning, it appears that letting Xojo have its way with my jpegs was costing me a factor of almost 6 in the resources folder of a build. (An unexpected bonus: since I am now managing my images, there is no need to have @1x versions in the resources folder. I can just downsample from @2x on the fly).

My executables are now down well under 100mbytes, which is tolerable.

FWIW, you will lose some sharpness when you downsample, so if that’s important to you, keep the 1x images.

Also, if you target Windows, you’ll also need a 3x image for users who have their screen set to 300%.

Yeah, I strongly discourage such an approach for user interface elements. In photos, it’s nearly impossible to notice, but in interface elements, it tends to stand out. Best results come from a vector designed at 1x (1pt = 1px) and having your design software produce the 2x and 3x versions from that.