백그라운드 스레드에서 이미지의 색상을 변경하려고합니다.
애플 문서는 UIGraphicsBeginImageContext 만 주 스레드에서 호출 할 수 있다고, 나는 CGBitmapContextCreate 사용하려고 해요 : (bitmapData와, pixelsWide, pixelsHigh, 8, // 비트 구성 요소 당UIGraphicsBeginImageContext vs CGBitmapContextCreate
컨텍스트 = CGBitmapContextCreate을
bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst);
나는 CGBitmapContext를 사용하여 두 번째를 UIGraphisBeginImageContext를 사용하여 첫 번째 "changeColor"의 두 가지 버전이 몹시 떠들어 대다.
첫 번째 것은 올바르게 색상을 변경하지만 두 번째 색상은 올바르게 변경되지 않습니다.
왜 그런가요?
- (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;
}
- (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;
}
는
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;
}
실제로 iOS 4.0에서 UIKit 그리기 기능은 이제 스레드 안전 : http://www.cocoabuilder.com/archive/cocoa/296299-drawing-thread-safety-in-ios.html. 이것은'UIGraphicsBeginImageContext()'를 포함하는 것으로 보입니다. 4.0 이상의 코어 그래픽 구현은 필요하지 않을 수도 있습니다. –
은 신뢰할만한 견적입니까? http://stackoverflow.com/questions/4451855/uigraphicsbeginimagecontext-vs-cgbitmapcontextcreate-on-ios 거기에 대한 논쟁이 있습니다. 내 테스트 코드는 별도의 스레드에서 UIGraphicsBeginImageContext()로 사망했습니다. 비록 그것이 진짜 이유인지 100 % 확신 할 수는 없지만. – eugene
이것은 또 다른 질문입니다. 여러분이 iOS 4.0을 말할 때, iOS <4.0을 대상으로하지만 iOS> = 4.0으로 컴파일 할 때 적용됩니까? 또는 코드가 iOS> = 4.0 인 컴퓨터에서만 실행되어야합니까? – eugene