Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoding .png images to base64 produces several times more data than expected #25571

Closed
ARPasescu opened this issue Feb 2, 2019 · 6 comments
Closed
Labels

Comments

@ARPasescu
Copy link

ARPasescu commented Feb 2, 2019

Godot version: 3.0.6
OS: Windows 10 Pro

Issue description:
I tried encoding several image objects to base64 using Marshalls.variant_to_base64(), and what I found is that the encoding produces several times as as much data as it should on a blank file.

Tested it with a 91 KB image and it resulted in a 186 KB output, 2x the size of the image.
Tested it with a 134 KB image and it resulted in a 470 KB output, 3.5x the size of the image.

The images i was trying to encode are .png files, so I'm not entirely sure whether that plays a role in the file size or whether the output sizes are different for .jpg or other image files, however I ran the same .png files through an online image-to-base64 encoding website (https://www.base64-image.de/) and it produced outputs of 123 KB and 185 KB respectively, both of which corresponding to average estimates for the encoding of about 4/3 times the size of the image. I also tried to get the PoolByteArray raw data from the image object, thinking that it's perhaps encoding non-necessary information together with the image data, but it produced the exact same results.

Steps to reproduce:
Copy this code in a blank project GDScript, add any image you want encoded in base64 to the project and copy its path to the code.

var file = File.new()
var image = Image.new()
image.load("insert any image file path here for encoding")
file.open("temp-file.txt", File.WRITE)
file.store_line(Marshalls.variant_to_base64(image))
file.close()
@bruvzg
Copy link
Member

bruvzg commented Feb 2, 2019

This is expected. Image.load decodes source .png to the OpenGL texture and Marshalls.variant_to_base64 encodes this texture (and other Image metadata).

If you want to encode source .png, load it as File instead of Image.

@ARPasescu
Copy link
Author

ARPasescu commented Feb 2, 2019

You are right, I have updated my code to replace Image with File. To get all the data from the image i replaced the store_line parameter with Marshalls.variant_to_base64(image.get_buffer(image.get_len())) and it resulted in a 121 KB file which is exactly 4/3 of the original image size of 91 KB. Thanks for the help.

@LinuxUserGD
Copy link
Contributor

@Rriik So it is fixed?

@ARPasescu
Copy link
Author

the respective issue was fixed, however I'm stuck trying to figure out how to then load that saved base64 data onto another image object. I tried this so far

var file = File.new()
var image = File.new()
image.open("res://SamplePNG-100kb.png", File.READ)
file.open("temp-file.txt", File.WRITE)
file.store_line(Marshalls.raw_to_base64(image.get_buffer(image.get_len())))
file.close()

file.open("temp-file.txt", File.READ)
var load_data = file.get_as_text()
var result = Image.new()
result.load_png_from_buffer(Marshalls.base64_to_raw(load_data))
file.close()

However, it gives me an error saying J[30]Y[00]: invalid chunk type and then says the png is corrupted... though if I try to reconstruct the image with a base64 decoder it works just fine with the file output.

@ARPasescu
Copy link
Author

Nevermind, I changed file.store_line() to file.store_string() and it seems to be working without error now.

@groud groud added the archived label Feb 3, 2019
@groud groud closed this as completed Feb 3, 2019
@groud
Copy link
Member

groud commented Feb 3, 2019

Closing as solved then :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants