Plugin "bytemap" loadTexture alpha transparency color

Hello @StarCrunch,

I used the same image file “icon.png” for both external folder, documents directory and resource directory. It is tested on the Solar2D 2020.3600 simulator (on Windows) as well as the built windows “exe”.

The alpha with the bytemap texture seems to be always “solid white color”, instead of the expected “transparent”. A screenshot on the simulator is attached here,

Please see the codes used below,

local byteMap = require( "plugin.Bytemap" )
local texture1 = byteMap.loadTexture( {
	filename = "D:/Temp/icon.png",
	format = "rgba",
	is_absolute = true
} )
local image1 = display.newImage( texture1.filename, texture1.baseDir )
image1.x = display.contentWidth * 0.25
image1.y = display.contentCenterY 
local image2 = display.newImage( "icon.png", system.DocumentsDirectory )
image2.x = display.contentWidth * 0.5
image2.y = display.contentCenterY
local texture3 = byteMap.loadTexture( {
 	filename = "icon.png",
	format = "rgba"
} ) 
local image3 = display.newImage( texture3.filename, texture3.baseDir )
image3.x = display.contentWidth * 0.75
image3.y = display.contentCenterY 

Please help to advise if there is any step I have missed out to get the expected results of “image2” above. Thank you.

PS. The “icon.png” I used, same file for every directory and external folder, is attached here,

Hi @luantiang.

This might be a case of needing premultiplied alpha. I don’t apply that by default, since the plugin is designed around raw bytes. I’ll see about adding an option for it.

I have a few updates pending (delayed for boring reasons), in particular WebP loading, so maybe I can work it in as I finish those up.


Hello @StarCrunch,

Noted. Thanks for your prompt response. I look forward to the next update. In the mean time, I would work out a temporary workaround.

Once again. Many thanks for sharing your plugin.

I did finally get some work done on this lately and upload new binaries to the free plugins, so for a few platforms it should now work when you update. (iPhone is there, but still waiting on Mac. My Mac access is limited at the moment, so I’ve gotten some help from a user, but this isn’t exactly a great long-term solution.) The issue was indeed just premultiplied alpha; I’ve opted for the Principle of Least Surprise and made that the default now.

Also, regarding some of the other things I mentioned, I still need to update the docs, but if any of that interests you, here’s the code I was using to test:

main.lua (3.0 KB)

(Image files are all from this page or the others in that set, if I’m not mistaken.)

No surprises with the webp build settings; just follow the Bytemap lead and change the name.

1 Like

Hello StarCrunch,

Many thanks! I have tested with 2 of my simple test apps, with the same “png” file loading in different ways, running on Simulator on Windows and on built “exe”. I can verify them to be working as expected now.

[My workaround so far until now] This would save me the extra steps of copying from external folder to “system.TemporaryDirectory”, before loading, using “Tiny File Dialogs” plugin to select the file. And then to remove them later during “housekeeping”.

Many thanks!

PS> For some who may be keen, the docs for these plugins are at,
(1) bytemap plugin to load image file from external source,
(2) asset reader plugin to read file from external source (Android only),
(3) tiny file dialog plugin to select file using explorer and other (Desktop only)

1 Like

Hello @StarCrunch
It seems that png file can not loaded correctly on my ios devices (Ipad pro 2021 and iphone 6s).

Here is my test code. (69.0 KB)

Hi @S_JetJaguar.

Interestingly, somebody else just pointed this out to me. We confirmed the issue last night and I’m hoping to build and upload new binaries relatively soon, maybe tonight if I get the chance.

I’ve uploaded new builds, so should be working now. I added the premultiply optimization mentioned over here (I’d only just read about it, not used it :smile:) too.

There’s also now a bytemap:MakeSeamless(how) method (how can be “linear” or “radial”; will be the latter if absent), that will apply the technique from the first article here to the current contents.

1 Like

I tested on my ios devices. It works fine now.
Many Thanks!

1 Like

Hi @StarCrunch.
I had another problem when I use ‘graphics.newOutline’ to get the outline of the image file.
I test on my ios/mac devices (IPad pro and macbook pro 2019). Here is my screenshot.

Here is my test code. (69.7 KB)

I also test it on android devices(I use your ‘plugin.AssetReader’ plugin to read png file content), there is no difference between ‘plugin’ and ‘solar2d’. It seems like it’s mac/ios platform specific problem.
Here is the android screenshot.

@S_JetJaguar Hi.

I looked at the newOutline() code in the source, and I think I see what’s going on. It seems to assume a certain type of bitmap, so it looks for alpha in a certain channel, but the byte order can be switched around on some architectures. However, a Bytemap is not that kind of bitmap, so it incorrectly does the swap and ends up searching for alpha in the “red” channel, which will be 0 where the penguin is black.

A proper fix would account for troublesome bitmap types and adjust (or not) the channel index. There aren’t many types, so it probably isn’t too hard, but would need a PR and to get accepted and all that.

In the meantime, there should be a way to do this by performing a couple GetBytes() calls with “rgb” and “alpha” formats, piecing them back together in the expected way, then temporarily SetBytes()'ing the result. Kind of a mess and probably slow, but it’s a workaround. :slight_smile: I’ll see about testing this and writing that snippet later.

Hello! Sorry to bother you. Could you please tell me is there a way to fixed this issue? Thanks a lot.

Sorry, kept forgetting. :smiley:

I think it would go something like (in the sample you gave me):

  local rgba = bmap:GetBytes()

  if IsTroublesomeDevice then -- Apple etc.
    local swizzled = {}

    for i = 1, #rgba, 4 do
      local r, g, b, a = rgba:byte(i, i + 3)

      swizzled [#swizzled + 1] = string.char(a, r, g, b) -- swizzle the components...

    bmap:SetBytes(table.concat(swizzled )) -- ...and temporarily swap them in

  local aVertices = graphics.newOutline(2, bmap.filename, bmap.baseDir)
  drawOutline(a, aVertices)

  if IsTroublesomeDevice then
    bmap:SetBytes(rgba) -- restore it

I’m a bit too tired to test this right now, I think, but will try to take a look tomorrow if I don’t hear back from you. If this seems to be the problem I probably have an idea of a (kludge-y) test to detect it in newOutline.

Thanks for your prompt response. I tested this in my apple devices. Its seems to fixed the problem.
:grinning_face_with_smiling_eyes:I’m looking forward to seeing you fixed it in newOutline.

1 Like