It loads a JPEG from data. The JPEG has only RGB color information (e.g. its RGB only, no alpha data).
When App.SupportHiDPI is ON,
the immutableBitmap returned has .hasAlphaChannel=True
this is contrary to the documentation : http://developer.xojo.com/hidpi-support$picture
which says that .HasAlphaChannel is File-Specified.
When App.SupportHiDPI is OFF
the mutableBitmap returned has .hasAlphaChannel=False, as expected.
Hi Greg, I think you misunderstand: the bug is that the .hasAlphaChannel value is always TRUE when App.SupportHiDPI is ON. The documents indicate it should be specified by the file, which, in practice, means that it will be True or False depending on whether the source file was 24 bit (RGB) or 32 bit (RGBA).
This is not academic. My app loads pictures, processes them, and then saves them, with an option of PNG or JPEG. Since JPEG can’t hold an alpha channel, it’s very important to know whether the original source file had alpha or not.
I can probably add a hack workaround, such as:
Use MBS plugins to open the file type header and parse it for alpha/no alpha
use the RGBSurface from Picture.CopyMask and scan all the pixels to see if any are non-zero.
But I think it would be better if Picture.hasAlphaChannel worked like it did before according to the documentation.
In conclusion, I think that this is not only a bug, it’s also a regression, which makes my bug report technically correct (the best kind!)
Here is a workaround - it counts the number of non-blank pixels in the Mask, to determine if the source file did or did not have any alpha information.
It’s not terribly fast: benchmarking in a 64 bit build for macOS reveals it takes about 1000msec (one second) to process a 4096x4096 (16 megapixels) image. Smaller or larger images are proportionally faster/slower.
Public Function CountAlphaPixels(p as Picture) as integer
// workaround for https://forum.xojo.com/47184-picture-fromdata-gives-immutablebitmap-with-hasalphachannel-tru/last
dim t0 as double = Microseconds
dim m as picture = p.CopyMask
if m = nil then
return 0
end if
dim r as RGBSurface = m.RGBSurface
dim nNonBlankPixels as integer
#Pragma BackgroundTasks False
#Pragma BoundsChecking False
#Pragma NilObjectChecking False
dim xMax as integer = m.Width-1
dim yMax as integer = m.Height-1
dim result as boolean = false
for y as integer = 0 to yMax
for x as Integer = 0 to xMax
dim c as color = r.Pixel(x,y)
if c <> &c00000000 then
nNonBlankPixels = nNonBlankPixels + 1
end if
next
next
dim deltaT as double = (Microseconds - t0)/1000
system.debugLog CurrentMethodName + " took " + str(deltaT,"#") + " msec "
return nNonBlankPixels
End Function