Forum

> > Off Topic > Calculating texture XY from UV coordinates.
Forums overviewOff Topic overviewLog in to reply

English Calculating texture XY from UV coordinates.

10 replies
To the start Previous 1 Next To the start

old Calculating texture XY from UV coordinates.

MikuAuahDark
User Off Offline

Quote
The purpose for this is for my application. I'm creating an application (and also an API) that does extracts part of an image in a texture with format that I already known.



As you can see, there's 5 separated image in that file and I want to make a program which does extracts those 5 images. I have every data that I need to extract the image, so this is just a math problem (yea, I'm bad at math anyway).

I can simply copy the first image (the big one) into another buffer because it doesn't rotated nor flipped. But take a look at the images below it (the second image), it's both flipped and rotated.

I have the second image Vertex & UV coordinates map. Here it is:
Vertex 0: 0 0; UV 0: 0 0.6328125
Vertex 1: 88 0; UV 1: 0 0.71875
Vertex 2: 88 640; UV 2: 0.625 0.71875
Vertex 3: 0 640; UV 3: 0.625 0.6328125

Now, I want to copy that image to specific buffer. How can I make the buffer contain something like this?

I did not use OpenGL nor DirectX because it's not an application to render an image, rather than converting image. I just want to copy the transformed image into the buffer and save it as PNG (I already know how to save the buffer as PNG).

To make it clear: Example the coordinates 0,0 of that image is 0,735 in that texture. What is the formula to make 40,122 (in image) = 122,696 (in texture)?

Anyone can help me about this? (Google doesn't give anything useful or I'm typing wrong keyword).

PS: I'm dealing with 4 Bytes per Pixel.

old Re: Calculating texture XY from UV coordinates.

Nekomata
User Off Offline

Quote
I don't know if what you're saying is exactly what I'm thinking about but here goes. Around 1-2 years back I did something like this with C++ using Allegro (Game library).

The method is called clipping (I believe) an image. You load it, then clip a part of it into another variable, thus creating another image object.

You use this when you have a spritesheet and other stuff in game development. I used allegro so I had a ready function for me, but doing it from scratch would be something like loading the pixels into an array, accumulate and dump the selected ones in another and then rendering it.
It would be something like loading the matrix of pixels from the image in an array, making another selective array with 1/0 true/false which would denote whether this would have the code copy the new pixel to the returning array. And a clusterfuck of nested loops. You & I mutual with the hate relationship towards maths so it'd be better to select a library to do this for you.

That's just the concept, I haven't used any other libraries and I've forgot allegro entirely so I can't be much of use code-wise and might be wrong somewhere I'm not aware of. If you don't want to maths then the common option is to find a library to do it for you.

Have a look at these;
http://stackoverflow.com/questions/14365411/opencv-crop-image (C++ & OpenCV Library)
http://stackoverflow.com/questions/1855996/crop-image-in-php (PHP)

Edit: It can be done in other languages as well, I'm sure there'd be atleast 1 image library with respective to the language out there for free.
edited 1×, last 24.01.16 05:44:42 pm

old Re: Calculating texture XY from UV coordinates.

MikuAuahDark
User Off Offline

Quote
@user Nekomata: Thanks for the link, but I know how to crop an image from the buffer.

The thing that I did not know is how to transform those images by the given UV coordinates and get their buffer represented as RGBA8888 (4bpp).

I can simply crop the image but it will give me this result instead this result that what I expected.

@user _Yank: I'm using C++ and I'm not going to render anything (it's just a console application which crops image). So, Love2d is simply not an option.

old Re: Calculating texture XY from UV coordinates.

MikuAuahDark
User Off Offline

Quote
@user VADemon: Yep. I'm start to think so. All texture in the game that I use for example seems only having 2 characteristics. Not rotated & flipped or rotated & flipped.

Maybe I'll hardcode that thing into my application.

user VADemon has written
since your cropping seems to be correct.


Actually I cropped those images with Photoshop.

old Re: Calculating texture XY from UV coordinates.

VADemon
User Off Offline

Quote
Now I get what you want.

Vertex are the "corners" of an image. Derivated from your example for the 2nd image of this texure:
Vertex 0 - top left corner, (0,0) coordinates related to this texture
Vertex 1 - bottom left, 88px height difference between texture origin and this point
Vertex 2 - bottom right, 88px height and 640 width
Vertex 3 - top right corner, 0px height and 640px width difference

I don't think you want the relative coordinates inside this texture, rather the "UV" which mark these coordinates relative to the whole texture. 1 = 100%, 1024px and 0 = 0%, 0px.

UV 0 coordinates for the second image thus are:
x = 0 * 1024px = 0px
y = 0.6328125 * 1024px = 63.28125% * 1024 = 648px

So, because Vertex 0 is the top left corner (0,0) the actual coordinates of this corner are x: 0 and y: 648 pixels.

old Re: Calculating texture XY from UV coordinates.

Flacko
User Off Offline

Quote
I hope I understood your problem correctly:
You're trying to copy a sprite from a scene as rendered instead as it is stored in the texture.
Here's a cheap illustration: http://i.imgur.com/M2T9GOK.png

So you want to figure out a function that maps any X,Y position between the 4 vertices to it's corresponding U,V so you can copy the image in the same way it's rendered pixel by pixel (mind that the rendered image may appear rotated, mirrored, scaled, skewed, etc)

Here's an algorithm to get the corresponding UV for a given X,Y (assuming the image is not skewed)
1
2
3
4
5
6
7
8
9
10
let X be the input variable for a pixel's x-coord
let Y be the input variable for a pixel's y-coord

let V0 be any vertex i
let V1 be the opposite vertex given by (i+2) mod 4
let T0 be the texture coords (in UV) given for V0
let T1 be the texture coords (in UV) given for V1

output U is T0_u + (V0_x - X) / (V0_x - V1_x) * (T1_u - T0_u)
output V is T0_v + (V0_y - Y) / (V0_y - V1_y) * (T1_v - T0_v)

If the output U,V do not result in a nice integer number after multiplying by the texture's width and height, then the image is probably scaled and you may want to use some sort of interpolation (ie: more boring maths)
edited 1×, last 25.01.16 03:41:30 pm

old Re: Calculating texture XY from UV coordinates.

MikuAuahDark
User Off Offline

Quote
@user VADemon: Thanks for that, but how can I copy the buffer? I'm sure that my buffer will be like this instead

@user Flacko:
user Flacko has written
You're trying to copy a sprite from a scene as rendered instead as it is stored in the texture.

This is exactly I wanted. The image appears mirrored & rotated in texture but it's appear like this when rendered.

user Flacko has written
Here's a cheap illustration: http://i.imgur.com/M2T9GOK.png

Yep, but actually it mapped like this.


user Flacko has written
Here's an algorithm to get the corresponding UV for a given X,Y (assuming the image is not skewed)
1
...code stripped...


The algorithm looks like still maps X as left-right and Y as top-bottom. I can test it with Lua

Code test >


The image (in texture) have x as bottom-top and y as left-right based from their UV Coordinates. The image isn't scaled at all and I can calculate the differences between the UV map is equal with the image size.

Do you have any other solution?

old Re: Calculating texture XY from UV coordinates.

Flacko
User Off Offline

Quote
You're right about the code being wrong. I still think my illustration is right, though. From my experience with opengl I can tell that the V-axis starts from the top of the texture at 0.0 and ends at the bottom at 1.0

Here's my second attempt with lua:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function xy2uv(x, y, v0, v1, v2, v3, t0, t1, t2, t3)
	local xyw = math.abs (
		math.max(v0.x, v1.x, v2.x, v3.x) -
		math.min(v0.x, v1.x, v2.x, v3.x)
	)
	local xyh = math.abs (
		math.max(v0.y, v1.y, v2.y, v3.y) -
		math.min(v0.y, v1.y, v2.y, v3.y)
	)
	atotal = xyw * xyh

	local a0 = (x - v0.x) * (y - v0.y) / atotal
	local a1 = (v1.x - x) * (y - v1.y) / atotal
	local a2 = (v2.x - x) * (v2.y - y) / atotal
	local a3 = (x - v3.x) * (v3.y - y) / atotal
	
	return {
		u = t2.u * a0 + t3.u * a1 + t0.u * a2 + t1.u * a3
		v = t2.v * a0 + t3.v * a1 + t0.v * a2 + t1.v * a3
	}
end

old Re: Calculating texture XY from UV coordinates.

MikuAuahDark
User Off Offline

Quote
From my test, that's exactly what I want. Thank you so much, and sorry because I bothered you.

I'm going to put the code into the application and see the PNG result (and post it here).

EDIT: It works but the output looks bit grainy. Maybe because my double datatype doesn't big enough to contain the precision.

Anyway, if you want to take a look at the C++ code and maybe can fix the "grainy" thing, here you go. (It's totally optional).

Comparison >


Code >


EDIT2: Nevermind. I fixed it by simply replacing line 6 in the loop code with this:
rawBmp[x+y*timg->Width]=texbBmp[uint32_t(uv.U*tWidth+0.5)+uint32_t(uv.V*tHeight+0.5)*tWidth];
edited 2×, last 27.01.16 07:55:25 am
To the start Previous 1 Next To the start
Log in to replyOff Topic overviewForums overview