title: iOS PNG Alpha channel is solid when converting UIImage to CGImage for OpenGL
body: <p>I have several PNG images with alpha transparency.  These display properly when used for general Quartz stuff such as in the UI.  However when I go to take the image and get it into OpenGL I find that the data I get has a solid alpha of 255.  I am using what seems to be the usual UIImage convert to CGImage and render into a context.  I'll post relevant bits of code below.  </p>
  
  <p>I have done a lot of searching and finally stumbled upon a way around this and I wanted to share on here, but it is slow as it has to loop over every pixel, and copy that raw alpha into the alpha channel.  I'd love to know a way around this.  I haven't switched any PNG options in my build (not sure where to set that) to see if it helps..</p>
  
  <p>thanks</p>
  
  <p>First I get a UIImage from my app that I added like this:</p>
  
  <pre><code>UIImage *image = [UIImage imageNamed:imageName];
  </code></pre>
  
  <p>then i convert to a CGImageRef and I do the usual context create like this relevant line only:</p>
  
  <pre><code>CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height,
                                               bitsPerComponent, bytesPerRow,
                                               CGImageGetColorSpace(spriteImage),
                                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
  </code></pre>
  
  <p>Then these next two lines are the magic to get me at the REAL png raw data… I probably should check the RGBA vs other formats but I am lazy…  After that I draw the image, and then go back and fix up the alpha… yes I know I could do this in a single loop and skipping bytes this is more readable for now...</p>
  
  <pre><code>// THIS data actually HAS the alpha!!
  CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(spriteImage));
  GLubyte *pixels = (GLubyte *)CFDataGetBytePtr(data);
  
  // 3
  CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
  
  
  // Sadly we now have to loop and fix the ALPHA directly from the raw PNG source
  // data as otherwise we get wrong/missing alpha...
  for (int y=0; y &lt; height; ++y) {
      for (int x=0; x &lt; width; ++x) {
          int byteIndex = (bytesPerRow * y) + (x * bytesPerPixel);
  
          spriteData[byteIndex + 3] = pixels[byteIndex +3 ];
      }
  }
  </code></pre>
  
  <p>then I do the usual glTexture calls etc… and it works fine..  If I leave out the copy loop above I get solid sprites with no alpha.  If I do the above, my sprites draw correctly with transparency.</p>
  
  <p>I am aware of the whole pre-multiplied stuff iOS does but this seems broken…  At least hopefully the above might help someone but there must be a better way???</p>
  
  <p>Thoughts?  Thanks!</p>