Reputation: 136
Below is the rotation code from react-native-camera to support ZXING library detect barcode. Specificed link is here
private byte[] rotateImage(byte[] imageData, int width, int height) {
byte[] rotated = new byte[imageData.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
rotated[x * height + height - y - 1] = imageData[x + y * width];
}
}
return rotated;
}
imageData
is YUV_420_888 format
I know it's rotate a frame, but how it is really work? Is it rotate 90 or 180 degree? In clockwise or anticlockwise direction?
I'm struggle to test it with sample images I put in so completely dont understand it.
Upvotes: 3
Views: 316
Reputation: 24417
The code that you have posted rotates a 1 byte per pixel monochrome (grey-scale) image 90 degrees clockwise and returns it in a new byte array. It doesn't process any chroma information.
The YUV_420_888 image format stores an image in YUV format, where Y is the luma (grey-scale component) which is stored first in memory, and U and V are the chroma components which are stored after the luma. To save space, U and V are stored at half the horizontal and vertical resolution of the luma component.
Because the luma component is stored first, if you just ignore the chroma channels that come after it, you can treat it as a monochrome image, which is what the code is doing.
To do the actual rotation, the code is iterating over all the pixels in y and x. For each pixel, it calculates the new pixel location in the rotated image and copies it there.
Here is a badly-drawn diagram of what's happening:
The YUV_420_888 stores the pixels one row at a time, top-to-bottom, left-to-right. So the math to compute a pixel location is like this:
old_pixel_location = (y * width) + x
As you can see in the image, the old image width becomes the new image height and vice versa. The pixel position in the rotated image has a new_y value equal to the x value, and a new_x value which is y pixels to the left of the right side of the image.
new_width = height
new_height = width
new_x = (new_width - 1) - y
new_y = x
The new pixel position is:
new_pixel_location = (new_y * new_width) + new_x
// substituting gives:
new_x = (height - 1) - y
new_pixel_location = (x * height) + ((height - 1) - y)
// removing brackets and re-ordering:
old_pixel_location = x + y * width
new_pixel_location = x * height + height - y - 1
Upvotes: 3