开发者

iOS, Generated images, and masking

开发者 https://www.devze.com 2023-03-29 22:01 出处:网络
I\'m trying to generate an image that is lozenge-shaped and shows some percentage finished versus unfinished.The way I implemented this was as follows:

I'm trying to generate an image that is lozenge-shaped and shows some percentage finished versus unfinished. The way I implemented this was as follows:

  • Generate 2 rectangles - one the size of the filled region, the other the size of the empty rectange
  • Invoke UIGrapicsBeginImageContext() with the size of the rectangle I am interested in
  • Draw the 2 rectangles in the context side-by side
  • Grab the image from the context and end the context
  • Create a new masked image by using CGImageMaskCreate() followed by CGImageCreateWithMask() and extracting the masked image

I generate the filled and empty bitmaps using category extensions to UIImage, and then apply a static mask image to them.

The Problem: This works fine in the simulator, but the masking doesn't work on a real device.

Instead of including the code here, I'm including a link to a project that has the code. The relevant files are:

  • UIImage.h/UIImage.m: The category extension to UIImage that adds both the "create an image with a specified color" and "create a masked image using the supplied mask".
  • TLRangeDisplay.h/TLRangeDisplay.m: the code for my lozenge-shaped status display. The routine of interest there is fillWithRect().

Here is the code I added to UIImage (via a category):

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

+ (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size {
    CGRect rect = CGRectMake(0.0f, 0.0f, size.height, size.width);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

- (UIImage*) maskWith:(UIImage *)maskImage {
    CGImageRef maskRef = maskImage.CGImage;
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false);
    CGImageRef masked = CGImageCreateWithMask([self CGImage], mask);
    UIImage* image = [UIImage imageWithCGImage:masked];
    CFRelease(mask);
    CFRelease(masked);
    return image;
}

And here is the routine that does the masking:

-(void)fillWithRect {
    CGRect f = self.frame;

    CGFloat width = f.size.width;
    CGFloat fullRange = maxValue_ - minValue_;
    CGFloat filledRange = currentValue_ - minValue_;

    CGRect fillRect = CGRectMake(0, 0, (filledRange * width) / fullRange, f.size.height);
    CGRect emptyRect = CGRectMake(fillRect.size.width, 0, width - fillRect.size.width, f.size.height);

    UIImage *fillImage = nil;
    UIImage *emptyImage = nil;

    if(fillRect.size.width > 0) {
        fillImage = [UIImage imageWithColor:fillColor_ andSize:fillRect.size];
    }
    if(emptyRect.size.width > 0) {
        emptyImage = [UIImage imageWithColor:emptyColor_ andSize:emptyRect.size];
    }

    // Build the 2-color image
    UIGraphicsBeginImageContext(f.s开发者_StackOverflow中文版ize);

    [fillImage drawInRect:fillRect];
    [emptyImage drawInRect:emptyRect];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Mask it
    if(nil != maskImage_)
        image = [image maskWith:maskImage_];

    CGRect fullRect = CGRectMake(0, 0, f.size.width, f.size.height);

    // Merge ith with the shape
    UIGraphicsBeginImageContext(f.size);

    [image drawInRect:fullRect];
    [shapeImage_ drawInRect:fullRect];

    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [shownView_ removeFromSuperview];
    shownView_ = [[UIImageView alloc] initWithImage:image];

    [self addSubview:shownView_];

    if(nil != shownView_)
        [self bringSubviewToFront:shownView_];
}

The project can be downloaded from http://dl.dropbox.com/u/5375467/ColorPlayOS4.zip

Thanks for any insights on this problem!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号