How can i crop an image?

How can I crop an Image with mask and combine it with another image (background) on iPhone? (OpenGL ES 1.1 is preferred)

  • I need to combine three images the way I represent in attached file: 1) One image is background. It is 'solid' in sense it has no alpha channel. 2) Another one is sprite. Sprite lies upon background. Sprite may have its own alpha channel, background has to be visible in places where sprite is transparent. 3) There's a number of masks: I apply new mask to Sprite every frame. Mask isn't rectangular. In other words, visible pixel = pixel of background, if cropping mask corresponding color is white OR sprite is transparent; pixel of sprite otherwise (for example, corresponding mask's pixel is black). I'm working with cocos2d-iphone. Can I make such combination with cocos2d-iphone or with OpenGL ES 1.1? If any answer is YES, working code would be appreciated. If both answers is NO, is there another technology on iOS to make what I want (maybe Quartz2d or OpenGL ES 2.0) ? Mask format is not obligatory black for Sprite and white for Background. I can make Mask of required format, such as transparency for Background and white for Sprite if needed. P.S. There's another unanswered question of same kind: http://stackoverflow.com/questions/787783/possible-to-change-the-alpha-value-of-certain-pixels-on-iphone

  • Answer:

    Here is my answer for OpenGL. The procedure would be very different for Quartz. The actual code is pretty simple, but getting it exactly right is the tricky part. I am using a GL context that is 1024X1024 with the origin in the bottom left. I'm not posting my code because it uses immediate mode which isn't available in OpenGL|ES. If you want my drawing code, let me know and I'll update my answer. Draw the mask with blending disabled. Enable blending, set the GLBlendFunc(GL_DST_COLOR, GL_ZERO) and draw the bleed through texture. My mask is white where it should bleed through. In your question it was black. Now to draw the background, set the blend function to glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR) and draw the background texture. EDIT Here is the code I describe above. Please note that this will not work on iOS since there is no immediate mode, but you should be able to get this working in Macintosh project. Once that is working you can convert it to something iOS compatible in the Macintosh project and then move that code over to your iOS project. The renderMask() call is where the most interesting part is. renderTextures() draws the sample textures in the top row. static GLuint color_texture; static GLuint mask_texture; static GLuint background_texture; static float window_size[2]; void renderMask() { float texture_x=0, texture_y=0; float x=0, y=0; { glBindTexture(GL_TEXTURE_2D, mask_texture); glDisable(GL_BLEND); glBegin(GL_QUADS); glTexCoord2f(texture_x,texture_y); glVertex2f(x,y); glTexCoord2f(texture_x+1.0,texture_y); glVertex2f(x+512.0,y); glTexCoord2f(texture_x+1.0,texture_y+1.0); glVertex2f(x+512.0,y+512.0); glTexCoord2f(texture_x,texture_y+1.0); glVertex2f(x,y+512.0); glEnd(); } { glBindTexture(GL_TEXTURE_2D, color_texture); glEnable(GL_BLEND); glBlendFunc(GL_DST_COLOR, GL_ZERO); glBegin(GL_QUADS); glTexCoord2f(texture_x,texture_y); glVertex2f(x,y); glTexCoord2f(texture_x+1.0,texture_y); glVertex2f(x+512.0,y); glTexCoord2f(texture_x+1.0,texture_y+1.0); glVertex2f(x+512.0,y+512.0); glTexCoord2f(texture_x,texture_y+1.0); glVertex2f(x,y+512.0); glEnd(); } { glBindTexture(GL_TEXTURE_2D, background_texture); glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR); glBegin(GL_QUADS); glTexCoord2f(texture_x,texture_y); glVertex2f(x,y); glTexCoord2f(texture_x+1.0,texture_y); glVertex2f(x+512.0,y); glTexCoord2f(texture_x+1.0,texture_y+1.0); glVertex2f(x+512.0,y+512.0); glTexCoord2f(texture_x,texture_y+1.0); glVertex2f(x,y+512.0); glEnd(); } } // Draw small versions of the textures. void renderTextures() { float texture_x=0, texture_y=0; float x=0, y=532.0; float size = 128; { glBindTexture(GL_TEXTURE_2D, mask_texture); glDisable(GL_BLEND); glBegin(GL_QUADS); glTexCoord2f(texture_x,texture_y); glVertex2f(x,y); glTexCoord2f(texture_x+1.0,texture_y); glVertex2f(x+size,y); glTexCoord2f(texture_x+1.0,texture_y+1.0); glVertex2f(x+size,y+size); glTexCoord2f(texture_x,texture_y+1.0); glVertex2f(x,y+size); glEnd(); } { glBindTexture(GL_TEXTURE_2D, color_texture); x = size + 16; glBegin(GL_QUADS); glTexCoord2f(texture_x,texture_y); glVertex2f(x,y); glTexCoord2f(texture_x+1.0,texture_y); glVertex2f(x+size,y); glTexCoord2f(texture_x+1.0,texture_y+1.0); glVertex2f(x+size,y+size); glTexCoord2f(texture_x,texture_y+1.0); glVertex2f(x,y+size); glEnd(); } { glBindTexture(GL_TEXTURE_2D, background_texture); x = size*2 + 16*2; glBegin(GL_QUADS); glTexCoord2f(texture_x,texture_y); glVertex2f(x,y); glTexCoord2f(texture_x+1.0,texture_y); glVertex2f(x+size,y); glTexCoord2f(texture_x+1.0,texture_y+1.0); glVertex2f(x+size,y+size); glTexCoord2f(texture_x,texture_y+1.0); glVertex2f(x,y+size); glEnd(); } } void init() { GLdouble bounds[4]; glGetDoublev(GL_VIEWPORT, bounds); window_size[0] = bounds[2]; window_size[1] = bounds[3]; glClearColor(0.0, 0.0, 0.0, 1.0); glShadeModel(GL_SMOOTH); // Load our textures... color_texture = [[NSImage imageNamed:@"colors"] texture]; mask_texture = [[NSImage imageNamed:@"mask"] texture]; background_texture = [[NSImage imageNamed:@"background"] texture]; // Enable alpha blending. We'll learn more about this later glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); } void draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); renderMask(); renderTextures(); } void reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, width, 0.0, height); glMatrixMode(GL_MODELVIEW); window_size[0] = width; window_size[1] = height; } This shows the my three textures drawn normally (crop, bleed through, and background) and then combined below.

Oleg Trakhman at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

This is exactly the technology you are looking for: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html Apple technology is built to do exactly what you describe from the ground up - the page above will introduce you to the technology! Set aside "cocos" and so on for now. Enjoy. It is absolutely impossible that you would need the speed of raw OpenGL programming, for this task. It's just impossible. It would be like if you decided to write machine code from scratch, to get text and a menu bar on the screen, rather than just using Apple's text and menu bar systems!!

Joe Blow

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.