How to make an image from a display object with no loss of transparency

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
Well, here goes nothing - for the experienced among us! I've tried a lot of different things to get this working, but my main issue here is that saving a PNG file from a canvas seems to lose some of its transparency, creating a dark grey border around the image.

The loss in transparency ruins the image for its intended purpose, so I am looking for some help in figuring out how to save a snapshop of a display object without any loss in transparency.

Here's a sample image:


And here's the script:
Code:
var bootSaveTest = Scene_Boot.prototype.start;
Scene_Boot.prototype.start = function() {
  bootSaveTest.call(this);
  var saveImage = function(imageName, canvas) {
    var fs = require('fs');
    var path = require('path');
    var base = path.dirname(process.mainModule.filename);
    var dataURL = canvas.toDataURL("image/png", 1);
    var dirPath = base + '/';
    // Make File Name
    var fileName = dirPath + imageName + '.png';
    // Get Base 64 Data
    var base64Data = dataURL.replace(/^data:image/png;base64,/, "");
    // Write File
    fs.writeFileSync(fileName, base64Data, 'base64', function(err) { console.log(err); });
  };

  var bitmap = ImageManager.loadBitmap('', 'sheer', 0, 0);
  bitmap.addLoadListener(function(source) {
    var sprite = new Sprite(source);
    var canvas1 = Graphics._renderer.extract.canvas(sprite);
    sprite.setColorTone([-255, 0, 0, 0]);
    var canvas2 = Graphics._renderer.extract.canvas(sprite);
    saveImage('sheer_bitmap', source._canvas);
    saveImage('sheer_sprite', canvas1);
    saveImage('sheer_spriteColor', canvas2);
  }.bind(this, bitmap))
};
Or use the JS file included in this post instead.

If you run the example above you will see that the result produces an exact copy when saved directly from the bitmap, but when it saves from a canvas extraction it loses transparency.

I was wondering if anyone knows of a better method to take a snapshot of a display object and all its children and changes with no loss of transparency information.

Hope someone is able to come up with some ideas!
 

Attachments

Hudell

Dog Lord
Veteran
Joined
Oct 2, 2014
Messages
3,545
Reaction score
3,715
First Language
Java's Crypt
Primarily Uses
RMMZ
It's... complicated.

Pixi uses the getImageData HTML5 method to read the image data from the bitmap. This method returns all the information needed, including the transparency. Then it creates a new canvas and uses the putImageData method, but apparently there are some conditions to get the transparency right with that.

This stackoverflow question should help point a scripter in the right direction in case you get someone to look into this.

The getImageData and putImageData methods are called from inside by this line:

Code:
Graphics._renderer.extract.canvas(sprite);
 

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
Already tried that, unfortunately it's the same result :(

If anyone can get the above sample image working without any loss of transparency and show me the code, that'd be great!
 

LTN Games

Indie Studio
Veteran
Joined
Jun 25, 2015
Messages
704
Reaction score
631
First Language
English
Primarily Uses
RMMV
So drawing to an offscreen canvas does not work at all? That's interesting to hear, I assumed it would work for sure. If I get some free time today I'll give it a try and see what I can come up, I'll try a little more of an advanced version of that StackOverflow question because I feel it should work correctly.
If you don't mind me asking, what exactly is the end goal for extracting a sprite from the canvas? Maybe there is an alternative solution to this problem.
 

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
If you don't mind me asking, what exactly is the end goal for extracting a sprite from the canvas? Maybe there is an alternative solution to this problem.
The goal is what the snippet is doing. Saving a complete sprite or container as an image with no loss of quality or transparency. What I mean by complete is basically saving all the changes made to it as well, tones, rotation, scale, masks etc.
 
Last edited:

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,623
Reaction score
1,439
First Language
French
Primarily Uses
RMMV
The goal is what the snippet is doing. Saving a complete sprite or container as an image with no loss of quality or transparency. What I mean by complete is basically saving all the changes made to it as well, tones, rotation, scale, masks etc.
to be honest.
I do not understand too much the principle of safeguarding, and the objective.
This could be help with a video of what you wish to do.
Sometime show visual content helps better than read someone's goal.

From what I understand your project offers a system where the player personalizes a character with diferentfile png, then you wish to save an image of the character built by the player in the files in png with alpha channel.
But it will seem that this process destroys the quality of PNG.

There are 2 types of png, in png8 and png24.
Then there is value of compression, you not supposed to be seen some artifact by the compressor.
Artifact will present if compress in png8 or png24 with very very bad compression.

A video of the problem could help identify what's wrong!

i supose that png Base 64 are png8 ? 8*8 = 64 !???
di you try base on png24 576 .... ??? 24*24

This can help ...check if all code and decoder are ok ?
http://www.motobit.com/util/base64-decoder-encoder.asp
 
Last edited:

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
I'm not quite sure how a video would help - I'm trying to save an image from canvas, including its rotation, tone, mask etc. and retain its transparency. Currently, there's a loss of transparency, so I'm asking if someone knows of a way to save it while having no quality loss.

If you run the snippet I provided, it'll show what I'm trying to achieve, but with the no transparency results.

Here's an example of the image extracted from the bitmap, no quality loss:


And here it is saved from a sprite (note loss in transparency):


Here it is with a tone:


What I want is the quality of the bitmap one but with the sprites/containers.
 
Last edited:

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,623
Reaction score
1,439
First Language
French
Primarily Uses
RMMV
In png unlike jpeg, there is no raw quality factor.
Aside from if I am wrong, there are 2 universal compression formats for all compressors PNG.
  • PNG8 Quality loss(same like Gif256 8 bit === lossless compression
and
  • PNG24 Max High Quality. support for 16 million colors and the alpha chanel
and
  • PNG-32 , We see its very rarely.... And useless because the eye does not perceive as much color. for Professional only

if you have loss of transparency, is because it save at png8 , 8bit .!?
You should be able to see the image quality with a right click on these and proprety.
The png24 has no loss of transparency.
If you talk about quality loss I suppose the compressor compresses into 8bit?

ps: i download you picture and check it, is 32 bits and is not quality loss...
can you send the result ? whit the quality loss ?

If it is not possible to change the compression code, you can pre optimize your image in png 8. with photoshop or other tool.
This will avoid artifacts during the second compression in your project.
 
Last edited:

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
I really, really don't think it's an issue with PNG files here.

In my previous post I showed you the original image. It's a white top with a V neck, right? The V neck is actually transparent white. Saving it with containers and whatnot, ruins this transparency as you can see in the example that the V neck has suddenly turned grey.

Saving these images without containers works just fine! No transparency loss! As soon as there are any masks/tones/rotations, it'll turn like the example above.
 

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,623
Reaction score
1,439
First Language
French
Primarily Uses
RMMV
ok i understant I had not seen the pictures above .
I go according to my understanding of things.
It is your image that does not seem correct.

If I apply basic simulation filter, to try and get the original result 3er picture!
Your image has a very poor transparency at the base.
We dont talk loss quality here is on photoshop 32 bit project.
i get the same result render.
You need to work on your picture. !

afvaefvcer4er4e.jpg
 

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
Yeah I'm not following here, can you explain some more what you mean by I need to work on my picture? The language barrier is hindering me from understanding you.
 

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,623
Reaction score
1,439
First Language
French
Primarily Uses
RMMV
can you try with this optimised picture and told me if you get bad result ? [see upload file]
This took 1 minute to correct, so the result is probably not optimal.

The problem came from the pixelation of your alpha channel
avcafvaeg.jpg

try this file ...
optimised-png.png
 

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
It wasn't pixelized, it's supposed to look like that. And no matter how the alpha channel looks like, it should be a lossless compression in the end. You're going to get the same result with your image as well.

I don't think you seem to understand my problem here. Regardless of what image is being used - if the image has ANY transparency, those pixels will lose some transparency and turn grey when saved.

Thank you for the help, but I think you're misunderstanding and blaming the image, when the image doesn't even matter (the result is the same on any image).
 

Sarlecc

Veteran
Veteran
Joined
Sep 16, 2012
Messages
453
Reaction score
211
First Language
English
Primarily Uses
RMMV
Just curious but could you perhaps save the changed values in a JSON file instead of saving the whole PNG? Then when the player reloads the game it loads the values from the JSON file to change the image back to the changed version vs the default. So for example save:
Code:
{
"Red": 120,
"Green": 80,
"Blue": 160,
"Alpha": 200,
"Rotation": 100,
"Scale": 50
}
Unless the end goal is different I believe this would be fairly easy to pull off in comparison. Hope this helps. :)
 

Celianna

Tileset artist
Veteran
Joined
Mar 1, 2012
Messages
10,557
Reaction score
5,592
First Language
Dutch
Primarily Uses
RMMV
Nope, the endgoal is a simple image - not one that gets reloaded with a whole bunch of applied effects which would slow down FPS.


This is the system in question - there's a lot of tinting, masks, and applying overlays. These should all be saved into a single image without losing transparency.
 

SamJones

Autorun
Veteran
Joined
Jul 12, 2015
Messages
113
Reaction score
47
First Language
English
Primarily Uses
RMMV
Have you tried using Graphics._renderer.extract.pixels(sprite) instead of Graphics._renderer.extract.canvas(sprite)?
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

People3_5 and People3_8 added!

so hopefully tomorrow i get to go home from the hospital i've been here for 5 days already and it's driving me mad. I miss my family like crazy but at least I get to use my own toiletries and my own clothes. My mom is coming to visit soon i can't wait to see her cause i miss her the most. :kaojoy:
Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.

Forum statistics

Threads
105,868
Messages
1,017,093
Members
137,587
Latest member
Usagiis
Top