0

根据this question from 2008,使用石英面罩会导致崩溃!还是这样吗?

基本上,我想做的是在固定背景上绘制不同颜色的骰子,为每个骰子形状使用一个 png(有很多),并以某种方式在代码中添加颜色。

编辑:澄清一下,例如,我想使用一个 png 文件来制作以下所有内容:

红色模具蓝色模具白色模具

基本上,我想将图像的红色、绿色和蓝色分量乘以三个独立的常数,同时保持 alpha 不变。

4

2 回答 2

1

我最近在一个没有崩溃的 iPhone 应用程序中广泛使用了掩码。该链接中的代码似乎甚至没有使用蒙版,只是剪裁;唯一提到面具是他尝试过的其他东西。他更有可能是从后台线程调用它,这UIGraphicsBeginImageContext不是线程安全的。

在不确切知道您想要获得什么效果的情况下,很难就如何做到这一点给出建议。遮罩当然可以单独工作(以获得一种丝网印刷效果),也可以剪裁在更逼真的图像上绘制的覆盖颜色。我可能会使用蒙版或路径来设置剪辑,然后绘制模具图像(使用kCBGlendModeNormalor kCBGlendModeCopy),然后使用kCGBlendModeColor.

于 2011-05-01T01:44:44.927 回答
1

这是一个镜头。经测试,无泄漏。没有崩溃。

。H

#import <UIKit/UIKit.h>

@interface ImageModViewController : UIViewController {

}
@property (nonatomic, retain) IBOutlet UIButton *test_button;
@property (nonatomic, retain) IBOutlet UIImageView *source_image;
@property (nonatomic, retain) IBOutlet UIImageView *destination_image;
@property (nonatomic, assign) float kr;
@property (nonatomic, assign) float kg;
@property (nonatomic, assign) float kb;
@property (nonatomic, assign) float ka;


-(IBAction)touched_test_button:(id)sender;

-(UIImage *) MultiplyImagePixelsByRGBA:(UIImage *)source  kr:(float)red_k  kg:(float)green_k  kb:(float)blue_k  ka:(float)alpha_k;


@end

.m

#define BITS_PER_WORD       32
#define BITS_PER_CHANNEL    8
#define COLOR_CHANNELS      4
#define BYTES_PER_PIXEL     BITS_PER_WORD / BITS_PER_CHANNEL


#import "ImageModViewController.h"

@implementation ImageModViewController

@synthesize test_button;
@synthesize source_image;
@synthesize destination_image;
@synthesize kr;
@synthesize kg;
@synthesize kb;
@synthesize ka;


-(IBAction)touched_test_button:(id)sender
{

    // Setup coefficients

    kr = 1.0;
    kg = 0.0;
    kb = 0.0;
    ka = 1.0;

    // Set UIImageView image to the result of multiplying the pixels by the coefficients

    destination_image.image = [self MultiplyImagePixelsByRGBA:source_image.image kr:kr kg:kg kb:kb ka:ka];

}

-(UIImage *) MultiplyImagePixelsByRGBA:(UIImage *)source  kr:(float)red_k  kg:(float)green_k  kb:(float)blue_k  ka:(float)alpha_k
{

    // Get image information
    CGImageRef bitmap     = [source CGImage];
    int width             = source.size.width;
    int height            = source.size.height;
    int total_pixels      = width * height;

    // Allocate a buffer
    unsigned char *buffer = malloc(total_pixels * COLOR_CHANNELS);

    // Copy image data to buffer
    CGColorSpaceRef cs   = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(buffer, width, height, BITS_PER_CHANNEL, width * BYTES_PER_PIXEL, cs, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);
    CGColorSpaceRelease(cs);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), bitmap);
    CGContextRelease(context);

    // Bounds limit coefficients
    kr = ((((kr < 0.0) ? 0.0 : kr) > 1.0) ? 1.0 : kr);
    kg = ((((kg < 0.0) ? 0.0 : kg) > 1.0) ? 1.0 : kg);
    kb = ((((kb < 0.0) ? 0.0 : kb) > 1.0) ? 1.0 : kb);
    ka = ((((ka < 0.0) ? 0.0 : ka) > 1.0) ? 1.0 : ka);

    // Process the image in the buffer

    int offset = 0;     // Used to index into the buffer

    for (int i = 0 ; i < total_pixels; i++)
    {
        buffer[offset] = (char)(buffer[offset] * red_k);   offset++;

        buffer[offset] = (char)(buffer[offset] * green_k); offset++;

        buffer[offset] = (char)(buffer[offset] * blue_k);  offset++;

        buffer[offset] = (char)(buffer[offset] * alpha_k); offset++;
    }

    // Put the image back into a UIImage
    context = CGBitmapContextCreate(buffer, width, height, BITS_PER_CHANNEL, width * BYTES_PER_PIXEL, cs, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);
    bitmap  = CGBitmapContextCreateImage(context);
    UIImage *output = [UIImage imageWithCGImage:bitmap];

    CGContextRelease(context);
    free(buffer);

    return output;

}


- (void)dealloc
{
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
}
*/

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

我用两个 UIImageViews 和一个 UIButton 设置 xib。顶部 UIImageView 使用 Interface Builder 预加载了图像。触摸文本按钮,图像被处理并设置为第二个 UIImageView。

顺便说一句,我从你的帖子中复制了你的图标有点麻烦。由于某种原因,透明度效果不佳。我使用了我自己在 Photoshop 中创建的新的 PNG 测试图像,有和没有透明度,它都像宣传的那样工作。

当然,您在循环中所做的事情将根据您的需要进行修改。

注意字节序,它真的会把事情搞砸!

于 2011-05-04T05:53:31.980 回答