3

Currently i m capturing the screen using the glreadpixels(). the image captured is generally mirrored image hence i flipped back the image to normal. Now i want to rotate the captured data (image) by 90'degree. any idea how to do that ?

The code i m using to capture the screen data is :

CGRect screenBounds = [[UIScreen mainScreen] bounds];

int backingWidth = screenBounds.size.width;
int backingHeight =screenBounds.size.height;

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);


NSInteger myDataLength = backingWidth * backingHeight * 4;
GLuint *buffer;
if((buffer= (GLuint *) malloc(myDataLength)) == NULL )
    NSLog(@"error initializing the buffer");
glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// code for flipping back (mirroring the image data)    
for(int y = 0; y < backingHeight / 2; y++) {
    for(int xt = 0; xt < backingWidth; xt++) {
        GLuint top = buffer[y * backingWidth + xt];
        GLuint bottom = buffer[(backingHeight - 1 - y) * backingWidth + xt];
        buffer[(backingHeight - 1 - y) * backingWidth + xt] = top;
        buffer[y * backingWidth + xt] = bottom;
    }
}

Any idea how to rotate the data captured in buffer by 90'degree ? Thanks

Tornado
  • 1,069
  • 12
  • 28

2 Answers2

2
size_t at (size_t x, size_t y, size_t width)
{
    return y*width + x;
}

void rotate_90_degrees_clockwise (
    const pixel * in,
    size_t in_width,
    size_t in_height,
    pixel * out)
{
    for (size_t x = 0; x < in_width; ++x) {
        for (size_t y = 0; y < in_height; ++i)
            out [at (in_height-y, in_width-x, in_height)]
               = in [at (x, y, in_width)];
    }
}

Sometimes, nothing beats a minute with pencil-and-paper :-)

This could be optimised, if you maintain x_in and y_in versus x_out and y_out -- incrementing one and decrementing the other -- and by cacheing x in between the loops, but this is the basic idea.

spraff
  • 32,570
  • 22
  • 121
  • 229
  • hey i tried this code but it doesnt worked correctly . the image obtained is a distorted one..also i m making video of these frames , allocating another buffer in each loop will cause performance issue also i m getting exceptions for this particular code – Tornado Jul 20 '11 at 05:07
  • a) How is it distorted? Try it on a, say, 3*5 int array. b) You don't need a new buffer for each frame, you can re-use the old one. c) Nothing in the above code can throw, something else is going wrong. – spraff Jul 20 '11 at 07:53
  • K now i am using the same buffer old one and exceptions are removed. now the only thing left is distorted image. hey i not pretty sure how to check your code for 3*5 int array...as my image data is stored in GLuint type buffer which i think represents a flat array..m new to OpenGl thing – Tornado Jul 20 '11 at 10:38
  • In my snippet `pixel` could be any type. Create a static array of ints {{1,2,3,4,5},{10,20,30,40,50},...} and printf them before and after the transformation. The error should be immediately obvious. – spraff Jul 20 '11 at 10:50
  • i checked using the static array , and i m getting the wrong output using your snippet... – Tornado Jul 20 '11 at 12:37
  • Can you tell what the intention of my code is? Have you tried stepping through the test case? It's nice sometimes to help those who help themselves. – spraff Jul 20 '11 at 12:42
  • please pardon me for troubling you so much...i understood your code completely now getting the values that are flipped upside down i think i had flip the data back. there was an edit in the code ""out [at (in_height-y-1, in_width-x-1, in_height)] = in [at (x, y, in_width)];"" without which i was getting some garbage values. i will work on this 2marrow.. Thanks for help.. Regards – Tornado Jul 20 '11 at 13:13
  • I don't mind the trouble, but it would be nice to see a *demonstration* of your own efforts. – spraff Jul 20 '11 at 13:15
  • hey i tried the code ...i took an int array {1,2,3,4,5,6,7,8,9,10,11,12} height=3 and width=4 , applied your logic..the output was {12,8,4,11,7,3,10,6,2,9,5,1} height=4 and width=3; but if we rotate the input matrix 90 degree the output should be {9,5,1,10,6,2,11,7,3,12,8,4} height=4 and width=3; this signifies i have to flip the data to get the correct image Right ? – Tornado Jul 21 '11 at 05:04
  • Right, so replace `in_height-y` with `y` in the output line. – spraff Jul 21 '11 at 07:39
2

k finally i figured out the whole thing. For others who want to do the same here are the codes for rotating the image from pixel data by 90 degree, 180 degree, 270 degree resp:-

// Rotate 90
// height and width specifies corresponding height and width of image            
for (int h = 0, dest_col = height - 1; h < height; ++h, --dest_col)
{
    for (int w = 0; w < width; w++)
    {
        dest[(w * height) + dest_col] = source[h*width + w];
    }
}

// Rotate 180
for (int h=0, dest_row=(height-1); h < height; --dest_row, ++h)
{
    for (int w=0, dest_col=(width-1); w < width; ++w, --dest_col)
    {
        dest[dest_row * width + dest_col] = source[h*width + w];
    }
}

// Rotate 270
for (int h = 0, dest_col=0; h < height; ++dest_col, ++h)
{
    for (int w=0, dest_row=width-1; w < width; --dest_row, ++w)
    {
        dest[(dest_row * height) + dest_col] = source[h * width + w];
    }
}
Diego Pino
  • 11,278
  • 1
  • 55
  • 57
Tornado
  • 1,069
  • 12
  • 28