help imagedate:getPixel for love 11.3

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
oscaradalid
Prole
Posts: 11
Joined: Wed May 09, 2018 11:48 am

help imagedate:getPixel for love 11.3

Post by oscaradalid »

Sorry for my bad English.

I'm trying to learn love2d and I don't know how to get a pixel from a map or canvas.

if I run the example that comes with love2d from imageDate by default: getPixel shows this error. main.lua: 40 attempt to index global canvas (a nill value).

I have searched the internet and did not find any.
¿Can someone provide me with a simple code where I can read a pixel from a map and or canvas? Thanks.
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: help imagedate:getPixel for love 11.3

Post by BrotSagtMist »

"canvas" is not the name of the function but a placeholder for the name of your canvas.
In other words you need to create _canvas_ first before being able to use it.

Further canvas:getPixel was removed from the current Löve version. To get the colour of a pixel i use this line:
r,g,b= Canvas:newImageData( nil, nil,x,y, 1,1 ):getPixel(0,0)
obey
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: help imagedate:getPixel for love 11.3

Post by pgimeno »

Presumably oscaradalid will want to get more than one pixel, and repeating that line over and over is definitely not a good idea :)
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: help imagedate:getPixel for love 11.3

Post by BrotSagtMist »

If you do know a better way then please say so, i am currently running this 20 times each frame to get points on my map and i am not happy with it.
obey
oscaradalid
Prole
Posts: 11
Joined: Wed May 09, 2018 11:48 am

Re: help imagedate:getPixel for love 11.3

Post by oscaradalid »

True, I want to do multiple get _pixel of a map. One way would be to save the map in an array and manipulate it from there, but I have no idea how to do it in this language. I'm learning lua and I want to pass this illustrative example from pico to love2d. ..

Code: Select all



cls(7)

-- seed the agar
for start=0,25,1 do
 pset(rnd(128),rnd(128),0)
end

-- speed
grabbing=2000

function _draw()
 for grab=0,grabbing,1 do
  local x=rnd(128)
  local y=rnd(128)
  local c=pget(x,y)

  if c~=7 then
   circfill(x,y,1,0)
  end
 end
end



User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: help imagedate:getPixel for love 11.3

Post by pgimeno »

Well, Pico8 is designed to work with a framebuffer, and Löve isn't designed to do that, but there are ways around it.

circfill with a radius of 1 is just 5 points: up, down, left, right and centre. Using that, you can implement a simple purpose-specific circfill that only does that.

Code: Select all

-- Set filter to nearest for all textures by default
love.graphics.setDefaultFilter("nearest", "nearest")

-- Create framebuffer
local fb = love.image.newImageData(128, 128)

-- Fill the framebuffer with white
fb:mapPixel(function (x, y)
  return 1, 1, 1, 1
end)

local function circfill(x, y, r, g, b)
  fb:setPixel(x, y, r, g, b, 1)
  if y > 0 then
    fb:setPixel(x, y-1, r, g, b, 1)
  end
  if x > 0 then
    fb:setPixel(x-1, y, r, g, b, 1)
  end
  if x < 127 then
    fb:setPixel(x+1, y, r, g, b, 1)
  end
  if y < 127 then
    fb:setPixel(x, y+1, r, g, b, 1)
  end
end

local function rnd(n)
  return love.math.random(0, n-1)
end

-- Plant the seeds
for i = 1, 26 do
  fb:setPixel(rnd(128), rnd(128), 0, 0, 0, 1)
end

-- Create a GPU-side image from our CPU-side framebuffer
local img = love.graphics.newImage(fb)

local grabbing = 2000

function love.update(dt)
  -- Update the framebuffer
  for i = 1, grabbing do
    local x = rnd(128)
    local y = rnd(128)
    local c = fb:getPixel(x, y)
    if c == 0 then
      circfill(x, y, 0, 0, 0)
    end
  end
end

function love.draw()
  -- Send the framebuffer to the GPU
  img:replacePixels(fb)
  -- Draw the image
  local w, h = love.graphics.getDimensions()
  local min = math.min(w, h)
  love.graphics.draw(img, w/2, h/2, 0, min/128, min/128, 64, 64)
end
Note that this doesn't work at 30 Hz like Pico-8 does, it works at the refresh rate of the monitor (60 Hz in many cases, but it can be different depending on the monitor and graphics mode). It can be refined further with a timer, to make it work at 30 Hz; just replace love.update with this:

Code: Select all

local timer = 0
function love.update(dt)
  if timer <= 0 then
    -- Update the framebuffer
    for i = 1, grabbing do
      local x = rnd(128)
      local y = rnd(128)
      local c = fb:getPixel(x, y)
      if c == 0 then
        circfill(x, y, 0, 0, 0)
      end
    end
    timer = timer + 1/30
  end
  timer = timer - dt
end

BrotSagtMist wrote: Sun Dec 05, 2021 11:15 pm If you do know a better way then please say so, i am currently running this 20 times each frame to get points on my map and i am not happy with it.
If you can't convert it to a framebuffer-based approach like the above, it might be better to convert to ImageData once and then grab the pixels from the ImageData.
oscaradalid
Prole
Posts: 11
Joined: Wed May 09, 2018 11:48 am

Re: help imagedate:getPixel for love 11.3

Post by oscaradalid »

Thank you very much for the example code, it is really good to understand the mechanics in love2d.
User avatar
UnixRoot
Citizen
Posts: 80
Joined: Mon Nov 08, 2021 8:10 am

Re: help imagedate:getPixel for love 11.3

Post by UnixRoot »

pgimeno wrote: Mon Dec 06, 2021 1:01 pm Well, Pico8 is designed to work with a framebuffer, and Löve isn't designed to do that
Isn't the Canvas object exactly that? A Framebuffer?
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: help imagedate:getPixel for love 11.3

Post by pgimeno »

UnixRoot wrote: Tue Dec 07, 2021 5:36 pm Isn't the Canvas object exactly that? A Framebuffer?
Well, the word is somewhat ambiguous :) I was referring to a CPU based framebuffer where drawing consists of writing to its memory. Kinda like many computers like the ZX Spectrum, and some consoles like the GBA, have. Pico-8 works like that.

That's the same interpretation used in this thread (a framebuffer library): https://love2d.org/forums/viewtopic.php?f=5&t=85013
Post Reply

Who is online

Users browsing this forum: No registered users and 18 guests