[SOLVED] Merge a grayscale image as an alpha channel


#1

Hi,
I am trying to “hack” the spritesheets limitations by using JPG images with alpha channel.
Using JPGs is useful when the frames of the sequence are too complex and rich of details to be saved in PNG format without obtaining a very big file.

The process is simple:

  • I have a starting PNG with alpha channel
  • from this PNG I save a JPG (with varying fill colour for originally transparent areas)
  • from the PNG I extract the alpha channel and save it as an opaque indexed colour grayscale image
  • I load the new JPG and the grayscale PNG, and use the PNG as alpha channel for the JPG.

These are the two images, the JPG and the grayscale PNG

animBitmapData is BitmapData from the JPG
animBitmapData_ALPHA is BitmapData from the grayscale PNG

I did everything, but the last step doesn’t work, animBitmapData is still opaque

animBitmapData.copyChannel(animBitmapData_ALPHA, animBitmapData_ALPHA.rect, new Point(0, 0), BitmapDataChannel.RED, BitmapDataChannel.ALPHA);

animBitmapData.transparent returns false, could this be the problem?


#2

JPEGS are loaded as RGB bitmapData and don’t have an alpha channel. You’ll need to create another BitmapData instance (with the same dimensions and alpha transparency set to true) and then you can use the copyPixels command and pass in animBitmapData as your sourceBitmap and your animBitmapData_ALPHA as the optional alphaBitmapData…

However I’ve noticed that the BitmapData API has a lot of issues for the HTML5 target so your mileage may vary.


#3

Yes, creating a new BMD with transparency and copying pixels from the opaque image is the approach I am following.


#4

I have a working trick for transparent JPGs: you need

  • (opaque) JPG for color data
  • opaque grayscale image (prefer PNG to JPG, usually PNG is best for this kind of images) for alpha channel, as shown in the first post.

The correct process (at least mine) for creating transparent spritesheets from JPGs is:

1 - load the source JPG

var sourceBMD: BitmapData = Assets.getBitmapData(source);

2 - create a BMD -with transparency- otherwise I can’t add an alpha channel

var destBMD: BitmapData = new BitmapData(sourceBMD.width, sourceBMD.height, true);

3 - load the source image for alpha channel

var sourceBMD_ALPHA: BitmapData = Assets.getBitmapData(alphaSource);

4 - draw the source JPG on the transparent BitmapData

destBMD.draw(sourceBMD);

5 - copy a channel from the opaque grayscale PNG (RED, GREEN or BLUE is the same, they are identical)

destBMD.copyChannel(sourceBMD_ALPHA, sourceBMD_ALPHA.rect, new Point(0, 0), BitmapDataChannel.RED, BitmapDataChannel.ALPHA);

6 - discard the JPG

sourceBMD.dispose();

…and you’re done! This process works in Flash and HTML5, I haven’t tested the other targets.


@dimumurray : as you said, targeting HTML5 the bitmapdata processing is different and could lead to undesired effects, but I managed to avoid the problem successfully.

There is an alternative way to achieve the result, but for now it works in Flash only: in place of the 2 steps DRAW-COPYCHANNEL (4-5) you could do COPYPIXEL, drawing and applying alpha in a single step:

destBMD.copyPixels(sourceBMD, sourceBMD.rect, new Point(0, 0), sourceBMD_ALPHA);

In Flash the result is correct, but uses more memory and in HTML5 I obtain an all-white-frames animation, with correct alpha channel but unusable. I think it will be fixed sooner or later.


#5

I think you have your channels mixed:

animBitmapData.copyChannel(animBitmapData_ALPHA, animBitmapData_ALPHA.rect, new Point(0, 0), BitmapDataChannel.RED, BitmapDataChannel.ALPHA);

Copy from the flat alpha graphic’s RED channel into the original image’s ALPHA channel, not the other way around :slight_smile:


#6

I will give another try to the grayscale image. :repeat:


Ok, I swapped the source and dest channels: it works with grayscale image too :slight_smile:
…editing previous posts…


#7

Hi, i have a project where i need to put in gray all the elements in the stage , so this goes very well using the colorMatrixFilter , exporting html work pretty well in the way it is has to be done (very smooth), but in neko goes very slow after the filter is applied

i dont know how to solve this, .anyone can help me with this, or give me an explanation about why in html works very fluid but dont in neko.

there are others solutions to archieve what im doing??, maybe using colortransform?? , i dont know what else to do.

this is the link to my project vega7.co/doc/ricoh ( press any red buttons to see the graymode effect )

im using openfl 7.1.2-LU2iAg , haxe 3.3.0 neko 2.1.0


#8

Are you talking about desaturation? If so, I suggest to open a new topic or better first search the forum, if you haven’t done it yet.


#9

Hi, desaturation is achieve but when the filter is applied ,my animations run very slow in neko, in html run very smooth , did you have any sugestion or solution for this, thanks,.


#10

Hi,

I haven’t played much with Neko yet, my understanding is that it’s fast to compile to but rendering is pretty slow because it’s not hardware-accelerated. Manipulating pixels on a whole scene sounds like something Neko will do pretty slowly (depending on the scene’s dimension, content etc of course).

If you need to have your project running on both html and desktop/mobile it will perform much better compiling to c++ or flash/AIR