views:

29

answers:

1

Hi folks, accordingly to some UIColor values from within a scroll views context I want to change the pixels rgb values for several UIImages I want to overlay afterwards. At least I have 4 images I'd like to overlay, a background image which is static and 3 layer images whose pixels information I'd like to change before overlaying all together. The problem I'm struggling with is that the UIImages are colored incorrectly. I remember somewhere I read something about difficulties concerning threading problems. But I'm not sure if this is the same problem in my code:

The scrollViewDidEndDecelerating delegate method takes the 3 layer images and passes them to the method which does the color changing for the pixels.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
 MyViewController *controller = [scrollViewControllers objectAtIndex:currentScrollViewPage];
 int color1 = [self getIntFromUIColor:controller.view1.backgroundColor];
 int color2 = [self getIntFromUIColor:controller.view2.backgroundColor];
 int color3 = [self getIntFromUIColor:controller.view3.backgroundColor];
 UIImage *bgImage = [UIImage imageName:@"bg.png"];


    //pass the overlay images to the coloring method 
    //I suppose my problem to be here
 UIImage *layer1 = [self convertImage:[UIImage imageName:@"layer1.png"] withColor:color1];
 UIImage *layer2 = [self convertImage:[UIImage imageName:@"layer2.png"] withColor:color2];
 UIImage *layer3 = [self convertImage:[UIImage imageName:@"layer3.png"] withColor:color3];

 CGSize sizeBG = bgImage.size;

 CGRect bgBoundingBox = CGRectMake (0, 0, sizeBG.width,sizeBG.height);

 CGContextRef myBitmapContext = [self createBitmapContextOfSize:sizeBG];

    //here I'd like to overlay the images
    CGContextDrawImage(myBitmapContext, bgBoundingBox, bgImage.CGImage);
 CGContextDrawImage(myBitmapContext, bgBoundingBox, layer1.CGImage);
 CGContextDrawImage(myBitmapContext, bgBoundingBox, layer2.CGImage);
 CGContextDrawImage(myBitmapContext, bgBoundingBox, layer3.CGImage);

 UIImage *result = [UIImage imageWithCGImage: CGBitmapContextCreateImage (myBitmapContext)];

 CGContextRelease (myBitmapContext);
    //finally paint the result on the imageView
 imageView.image = result;

}

this following method gets the UIImage and the color:

-(void) convertImage:(UIImage *)src_img withColor:(int)color
{
 [src_img retain];

  CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
  /*
   * Note we specify 4 bytes per pixel here even though we ignore the
   * alpha value; you can't specify 3 bytes per-pixel.
   */
  int height = src_img.size.height;
  size_t d_bytesPerRow = src_img.size.width * 4; 
  unsigned int * imgData = (unsigned int*)malloc(src_img.size.height*d_bytesPerRow);

  CGContextRef context =  CGBitmapContextCreate(imgData, src_img.size.width, 
               src_img.size.height, 
               8, d_bytesPerRow, 
               d_colorSpace, 
               kCGImageAlphaPremultipliedLast);

  UIGraphicsPushContext(context);
  // These next two lines 'flip' the drawing so it doesn't appear upside-down.
  CGContextTranslateCTM(context, 0.0, src_img.size.height);
  CGContextScaleCTM(context, 1.0, -1.0);
  // Use UIImage's drawInRect: instead of the CGContextDrawImage function, otherwise you'll have issues when the source image is in portrait orientation.
  [src_img drawInRect:CGRectMake(0.0, 0.0, src_img.size.width, src_img.size.height)];
  UIGraphicsPopContext();

  //swap colors
  int red = (color & 0xff0000) >> 16;
  int green = (color & 0xff00) >> 8;
  int blue = (color & 0xff);
  int colorShifted = (blue << 16) + (green << 8) + red;

            //in this function the pixels are manipulated
  colorChanger((int *)imgData,(src_img.size.height * src_img.size.width),colorShifted);

  // After we've processed the raw data, turn it back into a UIImage instance.
  CGImageRef new_img = CGBitmapContextCreateImage(context);
  UIImage * convertedImage = [[[UIImage alloc] initWithCGImage:
          new_img] autorelease];


  CGImageRelease(new_img);
  CGContextRelease(context);
  CGColorSpaceRelease(d_colorSpace);
  free(imgData);
  [src_img release];

            return convertedImage;

}

Any help would be appreciated. The changeColor function works quiet good. When I only change the color of one single layer the result looks good. But changing the colors of all 3 layers at the same time mostly layer2 and layer3 are painted with color3 and layer1 is painted with color2. Thanks for your help...