title: UIGraphicsBeginImageContext vs CGBitmapContextCreate
body: <p>I'm trying to change color of an image in a background thread.<br>
  Apple doc says UIGraphicsBeginImageContext can only be called from main thread, and I'm trying to use CGBitmapContextCreate:</p>
  
  <blockquote>
    <p>context = CGBitmapContextCreate
    (bitmapData,
                                     pixelsWide,
                                     pixelsHigh,
                                     8,      // bits per component                 </p>
  
  <pre><code>                             bitmapBytesPerRow,
                               colorSpace,
                               kCGImageAlphaPremultipliedFirst);
  </code></pre>
  </blockquote>
  
  <p>I have two versions of "changeColor" first one using UIGraphisBeginImageContext, second one using CGBitmapContextCreate.</p>
  
  <p>The first one correctly changes color, but second one doesn't.<br>
  Why is that?  </p>
  
  <pre><code>- (UIImage*) changeColor: (UIColor*) aColor
  {
      if(aColor == nil)
          return self;
  
      UIGraphicsBeginImageContext(self.size);
  
      CGRect bounds;
      bounds.origin = CGPointMake(0,0);
      bounds.size = self.size;
      [aColor set];
  
      CGContextRef context = UIGraphicsGetCurrentContext();
      CGContextTranslateCTM(context, 0, self.size.height);
      CGContextScaleCTM(context, 1.0, -1.0);
  
      CGContextClipToMask(context, bounds, [self CGImage]);
      CGContextFillRect(context, bounds);
  
      UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      return img;
  }
  </code></pre>
  
  <hr>
  
  <pre><code>- (UIImage*) changeColor: (UIColor*) aColor
  {
      if(aColor == nil)
          return self;
  
      CGContextRef context = CreateARGBBitmapContext(self.size);
  
      CGRect bounds;
      bounds.origin = CGPointMake(0,0);
      bounds.size = self.size;
  
      CGColorRef colorRef = aColor.CGColor;
      const CGFloat *components = CGColorGetComponents(colorRef);
      float red = components[0];
      float green = components[1];
      float blue = components[2];
  
      CGContextSetRGBFillColor(context, red, green, blue, 1);
  
  
      CGContextClipToMask(context, bounds, [self CGImage]);
      CGContextFillRect(context, bounds);
  
      CGImageRef imageRef = CGBitmapContextCreateImage(context);
      UIImage* img = [UIImage imageWithCGImage: imageRef];
      unsigned char* data = (unsigned char*)CGBitmapContextGetData (context);  
      CGContextRelease(context);
      free(data);
  
      return img;
  }
  </code></pre>
  
  <hr>
  
  <pre><code>CGContextRef CreateARGBBitmapContext(CGSize size)
  {
      CGContextRef    context = NULL;
      CGColorSpaceRef colorSpace;
      void *          bitmapData;
      int             bitmapByteCount;
      int             bitmapBytesPerRow;
  
      // Get image width, height. We'll use the entire image.                                                                                                                                                                                 
      size_t pixelsWide = size.width;
      size_t pixelsHigh = size.height;
  
      // Declare the number of bytes per row. Each pixel in the bitmap in this                                                                                                                                                                
      // example is represented by 4 bytes; 8 bits each of red, green, blue, and                                                                                                                                                              
      // alpha.                                                                                                                                                                                                                               
      bitmapBytesPerRow   = (pixelsWide * 4);
      bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
  
      // Use the generic RGB color space.                                                                                                                                                                                                     
      colorSpace = CGColorSpaceCreateDeviceRGB();
  
      if (colorSpace == NULL)
      {
          fprintf(stderr, "Error allocating color space\n");
          return NULL;
      }
  
      // Allocate memory for image data. This is the destination in memory                                                                                                                                                                    
      // where any drawing to the bitmap context will be rendered.                                                                                                                                                                            
      bitmapData = malloc( bitmapByteCount );
      if (bitmapData == NULL)
      {
          fprintf (stderr, "Memory not allocated!");
          CGColorSpaceRelease( colorSpace );
          return NULL;
      }
      // Create the bitmap context. We want pre-multiplied ARGB, 8-bits                                                                                                                                                                       
      // per component. Regardless of what the source image format is                                                                                                                                                                         
      // (CMYK, Grayscale, and so on) it will be converted over to the format                                                                                                                                                                 
      // specified here by CGBitmapContextCreate.                                                                                                                                                                                             
      context = CGBitmapContextCreate (bitmapData,
                                       pixelsWide,
                                       pixelsHigh,
                                       8,      // bits per component                                                                                                                                                                          
                                       bitmapBytesPerRow,
                                       colorSpace,
                                       kCGImageAlphaPremultipliedFirst);
      if (context == NULL)
      {
          free (bitmapData);
          fprintf (stderr, "Context not created!");
      }
  
      // Make sure and release colorspace before returning                                                                                                                                                                                    
      CGColorSpaceRelease( colorSpace );
  
      return context;
  
  }
  </code></pre>