Page 1 of 1

Copying an inclined area to a horizontal one?

Posted: Sat Apr 06, 2013 12:49 am
by agesome
Hi.

For my little project, I need to take a line (say, all pixels along a diagonal line) from an image and copy it to another image, one pixel high. As if taken with a line scan camera.
The most obvious way would seem to use a quad and render it to that one-pixel-high image, but apparently that's not possible (or so I've been told on IRC).
Then, I tried using ImageData and copying the pixels by hand. That seemed to work, but looks dirty and slow.

So, is there a way to take a non-horizontal area of an image, rotate it horizontally and store it in another image?
If there's no way to do that, would it work if I patched Love's OpenGL code to rotate quads?

Re: Copying an inclined area to a horizontal one?

Posted: Sat Apr 06, 2013 12:09 pm
by agesome
Love is indeed all-powerful. I have achieved desired function by rotating a Canvas' coordinate system around my line's origin point and drawing on it the image with the needed linear area now horizontal.

I actually needed this to take a sample of a racetrack image, simulating a line scan camera. Screenshot:
Image
(The green line is the sampling line, you can see results in upper left corner)

Relevant source code:

Code: Select all

local M = {}

local FRAME_LEN = 128
local sampling_angle = math.rad (90)
local x_shift = math.sin (sampling_angle + math.rad(90)) * FRAME_LEN
local y_shift = math.cos (sampling_angle + math.rad(90)) * FRAME_LEN

function M.sample(image, x, y)
	local w, h = image:getWidth(), image:getHeight()
	local canvas = love.graphics.newCanvas (w, h)
	local line = love.image.newImageData (FRAME_LEN, 1)

	love.graphics.push ()
	love.graphics.translate (x, y)
	love.graphics.rotate (sampling_angle)
	love.graphics.translate (-x, -y)
	canvas:renderTo (
		function ()
			love.graphics.draw (image, 0, 0)		
		end
	)
	love.graphics.pop ()
	local image_data = canvas:getImageData ()

	for i = 0, (FRAME_LEN - 1) do
		line:setPixel (i, 0, image_data:getPixel (x + i, y))
	end

	love.graphics.line (x, y, x + x_shift, y + y_shift)
	return love.graphics.newImage (line)
end

function M.set_sampling_angle(deg)
	sampling_angle = math.rad (deg)
	x_shift = math.sin (sampling_angle + math.rad(90)) * FRAME_LEN
	y_shift = math.cos (sampling_angle + math.rad(90)) * FRAME_LEN
end

return M

Re: Copying an inclined area to a horizontal one?

Posted: Sat Apr 06, 2013 12:20 pm
by Ragzouken
You found a solution whilst I was writing this, but I'll post it anyway for anyone who might be interested:

It will be possible will Geometry, which I understand will be in 0.9.0, so if it's not urgent then I'd hold your horses on patching love yourself.

You could hack it will a pixel effect, but that's probably a bad idea for compatibility reasons. If you did want to do that for now though, the effect would be something like:

Code: Select all

extern number w, h; // width/height of source image
extern number ox, oy, a; // line start and angle

vec4 effect(vec4 colour, Image image, vec2 local, vec2 pixel)
{
    vec2 source = vec2(ox + cos(a) * pixel.x, oy + sin(a) * pixel.x);

    source.x /= w;
    source.y /= h;

    return Texel(image, source);
}

Re: Copying an inclined area to a horizontal one?

Posted: Sun Apr 07, 2013 5:18 pm
by agesome
Ragzouken, I have opted for your solution for now. Thank you. My approach turned out to be more difficult to use, especially because line angle is constantly changing.