iOS, сгенерированные изображения и маскировка - PullRequest
3 голосов
/ 22 августа 2011

Я пытаюсь создать изображение ромбовидной формы, показывающее процентное соотношение готовых и незавершенных изображений. Я реализовал это следующим образом:

  • Создайте 2 прямоугольника - один размер заполненной области, другой размер пустого прямоугольника
  • Invoke UIGrapicsBeginImageContext () с размером интересующего меня прямоугольника
  • Нарисуйте 2 прямоугольника в контексте бок о бок
  • Возьмите изображение из контекста и завершите контекст
  • Создайте новое замаскированное изображение с помощью CGImageMaskCreate () , за которым следует CGImageCreateWithMask () и извлеките замаскированное изображение

Я генерирую заполненные и пустые растровые изображения, используя расширения категорий для UIImage, а затем применяю к ним статическую маску.

Проблема: Это нормально работает в симуляторе, но маскирование не работает на реальном устройстве.

Вместо того, чтобы включать здесь код, я включаю ссылку на проект, в котором есть код. Соответствующие файлы:

  • UIImage.h / UIImage.m : Расширение категории для UIImage, которое добавляет как «создание изображения с заданным цветом», так и «создание маскированного изображения с использованием предоставленной маски».
  • TLRangeDisplay.h / TLRangeDisplay.m : код моего отображения статуса в форме ромба. Интересующая процедура здесь fillWithRect () .

Вот код, который я добавил в UIImage (через категорию):

+ (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;
}

А вот процедура, которая выполняет маскирование:

-(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.size);

    [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_];
}

Проект можно скачать с http://dl.dropbox.com/u/5375467/ColorPlayOS4.zip

Спасибо за понимание этой проблемы!

...