• 2D
  • Image.set_pixel sets wrong color

I'm trying to combine 2 small images, each 2 pixels wide, 2 pixel high. I'm storing them in a PoolByteArray and then create a new image based on this PoolByteArray. Due to how the PoolBytearray is filled it first has all the bits from the first image, then all the bits from the second. I save the image as png and see the colors are correct, but instead of 2 by 2 tiles, they line up as 4 by 1 rows. So I have to change them around a bit and set_pixel sounds ideal for that. I print the coordinates and colors to the debugger and they're the exact same colors as the original image. I save it to a png again, but the colors don't match. There's even a new one.

This is the code I use:

    var img_tex := ImageTexture.new()
var base_img : Image = base.get_data()
var base_pba :PoolByteArray = base_img.get_data()
var base_img2 : Image = base2.get_data()
var base_pba2 :PoolByteArray = base_img2.get_data()
base_pba.append_array(base_pba2)
var end_pba : PoolByteArray = PoolByteArray()
var end_img = Image.new()

var tile_width = 2
var tile_height = 2
var columns = 2
var rows = 1
var bits = 4

    end_img.create_from_data(columns * tile_width, rows * tile_height, false, Image.FORMAT_RGBA8, base_pba)
SpriteBuilder.save_to_png(end_img, "test2") #correct colors, just horizontal
end_img.lock()
for row in rows :
	for y in tile_height:
		for column in columns:
			for x in tile_width:
				var offset = (y * bits * columns) + (column * rows * tile_width * tile_height * bits) + (x * bits)
				var c = Color(
					base_pba[offset], base_pba[offset+1], 
					base_pba[offset+2], base_pba[offset+3]
				)
				end_img.set_pixel((column * tile_width) + x,(row * tile_height) + y, c)
				print("set pixel. x: " + str((column * tile_width) + x) + ", y: " + str((row * tile_height) + y) + ", offset: " + str(offset) + " - Color: " + str(c))
#x, y and colors all show correct in debugger
end_img.unlock()
SpriteBuilder.save_to_png(end_img, "test3")
#wrong colors for some reason

this is the print statement from the debugger:

set pixel. x: 0, y: 0, offset: 0 - Color: 110,68,128,255
set pixel. x: 1, y: 0, offset: 4 - Color: 64,132,180,255
set pixel. x: 2, y: 0, offset: 16 - Color: 255,0,0,255
set pixel. x: 3, y: 0, offset: 20 - Color: 252,255,0,255
set pixel. x: 0, y: 1, offset: 8 - Color: 255,255,255,255
set pixel. x: 1, y: 1, offset: 12 - Color: 0,0,0,255
set pixel. x: 2, y: 1, offset: 24 - Color: 18,255,0,255
set pixel. x: 3, y: 1, offset: 28 - Color: 0,60,255,255

This is just a test, the end goal is being able to take several tilemaps and bake it to a single texture. I've attached a zip file: pba.txt is the PoolByteArray as a text file PBArray_test.png is the first image PBArray_test2.png is the second image test2.png is the result from the first save_to_png() * test3.png is the result the second save_to_png()

Any ideas what I'm doing wrong here?

i think the problem is base_pba.append_array(base_pba2) you need change it. the function is just append a array to base_pba.you need two-dimensional array addition

Thanks, it could be a possible workaround for this setup, but later on I plan to blit and merge images and set_pixel() would be ideal. I 'd like to find out why it doesn't use the colors I tell it to use.

The other problem is, if I don't use create_image_from_data() like that, but use create_image() instead, it ignores the image 's lock() and throws errors that the image needs to be locked first before set_pixel can be used, even though I've stated to use the lock.

I've also tested to use set_pixel by handfeeding it only red for instance, but it fills everything with white instead. Black is the only one it correctly fills it with. But 1, 1, 1, 255 is no go and fills it with complete white instead.

If I recall correctly, the Color class takes inputs with the range 0-1, where values above 1 or below 0 are HDR colors. I think you need to use Color8 instead if you want to have the range be 0-255.

Wow, that's it! Didn't know Color8 existed, would've never found it. I added the 8 and it worked as intended. Thanks!