gpt4 book ai didi

ios - UIGraphicsBeginImageContext 与 CGBitmapContextCreate

转载 作者:可可西里 更新时间:2023-11-01 05:48:19 25 4
gpt4 key购买 nike

我正在尝试在后台线程中更改图像的颜色。
Apple 文档说 UIGraphicsBeginImageContext 只能从主线程调用,我正在尝试使用 CGBitmapContextCreate:

context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, // bits per component

                             bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);

我有两个版本的“changeColor”,第一个使用 UIGraphisBeginImageContext,第二个使用 CGBitmapContextCreate。

第一个正确地改变了颜色,但第二个没有。
这是为什么?

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

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

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;

}

最佳答案

您的第二种方法是做第一种方法从未做过的工作。下面是对第二种方法的调整,以更接近第一种方法:

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

CGContextSetFillColorWithColor(aColor.CGColor);

CGContextClipToMask(context, bounds, [self CGImage]);
CGContextFillRect(context, bounds);

CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage* img = [UIImage imageWithCGImage: imageRef];
CGContextRelease(context);

return img;
}

我所做的两个更改是我将其转换为使用 CGContextSetFillColorWithColor(),并且我删除了位图上下文的支持数据的危险且不正确的 free() .如果此代码片段的行为与第一个代码片段不同,则您必须查看 CreateARGBBitmapContext() 的实现以验证它是否正确。

当然,正如 Brad Larson 在评论中提到的,如果您的目标是 iOS 4.0 及更高版本,UIKit 图形方法(根据发行说明)是线程安全的,您应该能够使用第一种方法很好。

关于ios - UIGraphicsBeginImageContext 与 CGBitmapContextCreate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4683448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com