Image Renderer doesn't show correct image

Hello! I’m trying to make this image which will render a specific image. It’s mainly for fun. But i’ve come to an issue, the image will be rendered incorrectly.

Here’s the renderer:

and here’s the image:

you can very clearly see that they’re very different. Im pretty sure there is something wrong with how im getting the color from the table. Although i’m not sure.

This is my script:

local service = game:GetService("HttpService")
local thing = require(script.GreedyCanvas)
local url = "http://localhost:3000/api/img"

local data = service:GetAsync(url)

local decoded = service:JSONDecode(data)

local width = decoded[1].dimensions.width
local height = decoded[1].dimensions.height
local colors = decoded[1].colors

local Canvas = thing.new(width, height)
for y=1, height do
	for x=1, width do
		-- Define color
		local color_table = colors[x * y]
		local color = Color3.fromRGB(color_table['r'], color_table['g'], color_table['b'])
		
		-- Set in canvas
		Canvas:SetPixel(x, y, color)

		-- Draw naively for reference
		local pixel = Instance.new("Frame")
		pixel.BorderSizePixel = 0
		pixel.BackgroundColor3 = color
		pixel.Size = UDim2.fromScale(120/x, 120/y)
		pixel.Position = UDim2.fromOffset((x * 120) - 120, (y * 120 - 120))
		pixel.Size =  UDim2.fromOffset(120, 120)
		pixel.Parent = workspace.Part.SurfaceGui.Holder
		task.wait()
	end
end

-- Render canvas
Canvas:Render()


This is my backend if it’s needed


const jimp = require('jimp')
const express = require('express')
const app = express()
app.get('/api/img', async (req, res) => {
       jimp.read("./floor.png", async function (err, image) {
           let data = [{'dimensions': {'width': 0, 'height': 0}, 'colors': []}]
           data[0].dimensions.width = image.getWidth()
           data[0].dimensions.height = image.getHeight()
            for (let x = 0; x < image.getWidth(); x++) {
                for (let y = 0; y < image.getHeight(); y++) {
                    let hex = await image.getPixelColor(x,y); 
                    let rgb = await jimp.intToRGBA(hex);
                    data[0].colors.push(rgb)
                }
            }
            res.json(data) 
    });
    
    
})


app.listen(3000, () => {
    console.log('listening')
})

any help is appreciated! Thankd

fixed it. Turns out it was an issue with how I was getting the color. Before i’d do x * y. Turns out I have to make it check the x of the pixel + the y of the pixel and see if that match.

This is the new frontend

local service = game:GetService("HttpService")
local thing = require(script.GreedyCanvas)
local url = "http://localhost:3000/api/img"

local data = service:GetAsync(url)

local decoded = service:JSONDecode(data)

local width = decoded[1].dimensions.width
local height = decoded[1].dimensions.height
local colors = decoded[1].colors
local function GetPixel(pixels, x:number, y:number)
	for _, data in pairs(pixels) do
		if data then
			local data_x = data.x
			local data_y = data.y
			if data_y == y and data_x == x then
				return data
			end
		end
	end
end
local Canvas = thing.new(width, height)
for y=1, height do
	for x=1, width do
		-- Define color
		local color_table = GetPixel(colors, x, y)
		if color_table then
			local color = Color3.fromRGB(color_table['r'], color_table['g'], color_table['b'])

			-- Set in canvas
			Canvas:SetPixel(x, y, color)

			-- Draw naively for reference
			local pixel = Instance.new("Frame")
			pixel.BorderSizePixel = 0
			pixel.BackgroundColor3 = color
			local scale = 125
			pixel.Position = UDim2.fromOffset((x * scale) - scale, (y * scale - scale))
			pixel.Size =  UDim2.fromOffset(scale, scale)
			pixel.Parent = workspace.Part.SurfaceGui.Holder
			task.wait()
		end
		
	end
end

-- Render canvas
Canvas:Render()

and the new backend

const jimp = require('jimp')
const express = require('express')
const app = express()
app.get('/api/img', async (req, res) => {
       jimp.read("./floor.png", async function (err, image) {
           let data = [{'dimensions': {'width': 0, 'height': 0}, 'colors': []}]
           data[0].dimensions.width = image.getWidth()
           data[0].dimensions.height = image.getHeight()
            for (let x = 0; x < image.getWidth(); x++) {
                for (let y = 0; y < image.getHeight(); y++) {
                    let colors = data[0].colors
                    let hex = await image.getPixelColor(x,y); 
                    let rgb = await jimp.intToRGBA(hex);
                    let dataArray = {'r': rgb['r'],'b': rgb['b'],'g': rgb['g'], 'x': x, 'y':y}
                    colors.push(dataArray)
                }
            }
            res.json(data) 
    });
    
    
})


app.listen(3000, () => {
    console.log('listening')
})
1 Like