Why does my algorithm to convert between index and x,y with bitmap buffers result in the image being flipped vertically?
Bitmap usually starts from bottom-left corner and proceeds to top-right corner. But not always.
There is a value biHeight
in bitmap header file, if this value is negative, then bitmap is upside down, it starts from bottom-left. And if this value is positive then the bitmap starts from top-left.
If you have access to biHeight
then simply flip its value to show the bitmap right side up.
To make the calculations easier, pick any valid X/Y point, then find the corresponding source_index
in the buffer, as shown below. Copy that point in to your destination buffer.
Note that you need an additional loop to copy 4 bytes from source to destination (you don't have that in your code, so I am not sure how your code works at all)
for(let i = 0; i < bytes_per_pixel; i++)
buffer_cropped[dst_index + i] = buffer[source_index + i];
The code below should work for 32-bit images (4 bytes per pixel). Note that 24-bit images will need padding.
if (height < 0)
height = -height;
let bytes_per_pixel = 4;
let cropped_x = 10;
let cropped_y = 10;
let cropped_width = width / 2;
let cropped_height = height / 2;
if (new_x < 0 || new_x >= new_width ||
new_y < 0 || new_y >= new_height) { error... }
if (cropped_width < 1 || cropped_width > width ||
cropped_height < 1 || cropped_height > height) { error... }
let dst_index = 0;
for(let y = cropped_y; y < cropped_y + cropped_height; y++)
{
for(let x = cropped_x; x < cropped_x + cropped_width; x++)
{
//use for right-side up bitmap:
//int source_index = (y * width + x) * bytes_per_pixel;
////
//use for upside-down bitmap:
let source_index = ((height - y - 1)* width + x) * bytes_per_pixel;
////
for(let i = 0; i < bytes_per_pixel; i++)
buffer_cropped[dst_index + i] = buffer[source_index + i];
dst_index += bits_per_pixel;
}
}