gpt4 book ai didi

iphone - 转换为灰度 - 太慢

转载 作者:行者123 更新时间:2023-12-03 18:49:10 33 4
gpt4 key购买 nike

我创建了一个将图像转换为灰度的类。但它的工作速度太慢了。有没有办法让它运行得更快?

这是我的类(class):

@implementation PixelProcessing

SYNTHESIZE_SINGLETON_FOR_CLASS(PixelProcessing);

#define bytesPerPixel 4
#define bitsPerComponent 8


-(UIImage*)scaleAndRotateImage: (UIImage*)img withMaxResolution: (int)kMaxResolution
{
CGImageRef imgRef = img.CGImage;

CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);


CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);

if ( (kMaxResolution != 0) && (width > kMaxResolution || height > kMaxResolution) ) {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
}
else {
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
}
}

CGFloat scaleRatio;
if (kMaxResolution != 0){
scaleRatio = bounds.size.width / width;
} else
{
scaleRatio = 1.0f;
}

CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = img.imageOrientation;
switch(orient) {

case UIImageOrientationUp: //EXIF = 1
transform = CGAffineTransformIdentity;
break;

case UIImageOrientationUpMirrored: //EXIF = 2
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;

case UIImageOrientationDown: //EXIF = 3
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;

case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;

case UIImageOrientationLeftMirrored: //EXIF = 5
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;

case UIImageOrientationLeft: //EXIF = 6
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;

case UIImageOrientationRightMirrored: //EXIF = 7
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;

case UIImageOrientationRight: //EXIF = 8
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;

default:
[NSException raise:NSInternalInconsistencyException format: @"Invalid image orientation"];

}

UIGraphicsBeginImageContext(bounds.size);

CGContextRef context = UIGraphicsGetCurrentContext();

if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
}
else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
}

CGContextConcatCTM(context, transform);

CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *tempImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return tempImage;
}


#pragma mark Getting Ans Writing Pixels
-(float*) getColorForPixel: (NSUInteger)xCoordinate andForY: (NSUInteger)yCoordinate
{
int byteIndex = (bytesPerRow * yCoordinate) + xCoordinate * bytesPerPixel;

float *colorToReturn = malloc(3);
colorToReturn[0] = bitmap[byteIndex] / 255.f; //Red
colorToReturn[1] = bitmap[byteIndex + 1] / 255.f; //Green
colorToReturn[2] = bitmap[byteIndex + 2] / 255.f; //Blue

return colorToReturn;
}

-(void) writeColor: (float*)colorToWrite forPixelAtX: (NSUInteger)xCoordinate andY: (NSUInteger)yCoordinate
{
int byteIndex = (bytesPerRow * yCoordinate) + xCoordinate * bytesPerPixel;

bitmap[byteIndex] = (unsigned char) ( colorToWrite[0] * 255);
bitmap[byteIndex + 1] = (unsigned char) ( colorToWrite[1] * 255);
bitmap[byteIndex + 2] = (unsigned char) ( colorToWrite[2] * 255);
}

#pragma mark Bitmap

-(float) getAverageBrightnessForImage: (UIImage*)img
{
UIImage *tempImage = [self scaleAndRotateImage: img withMaxResolution: 100];

unsigned char *rawData = [self getBytesForImage: tempImage];

double aBrightness = 0;

for(int y = 0; y < tempImage.size.height; y++) {
for(int x = 0; x < tempImage.size.width; x++) {
int byteIndex = ( (tempImage.size.width * y) + x) * bytesPerPixel;

aBrightness += (rawData[byteIndex] + rawData[byteIndex + 1] + rawData[byteIndex + 2]);


}
}

free(rawData);

aBrightness /= 3.0f;
aBrightness /= 255.0f;
aBrightness /= tempImage.size.width * tempImage.size.height;

return aBrightness;
}

-(unsigned char*) getBytesForImage: (UIImage*)pImage
{
CGImageRef image = [pImage CGImage];
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);

bytesPerRow = bytesPerPixel * width;

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * bytesPerPixel);
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
CGContextRelease(context);

return rawData;
}

-(void) loadWithImage: (UIImage*)img
{
averageBrightness = [self getAverageBrightnessForImage: img];
currentImage = [self scaleAndRotateImage: img withMaxResolution: 0];

imgWidth = currentImage.size.width;
imgHeight = currentImage.size.height;

bitmap = [self getBytesForImage: currentImage];

bytesPerRow = bytesPerPixel * imgWidth;
}

-(void) processImage
{
// now convert to grayscale

for(int y = 0; y < imgHeight; y++) {
for(int x = 0; x < imgWidth; x++) {
float *currentColor = [self getColorForPixel: x andForY: y];

//Grayscale
float averageColor = (currentColor[0] + currentColor[1] + currentColor[2]) / 3.0f;

averageColor += 0.5f - averageBrightness;

if (averageColor > 1.0f) averageColor = 1.0f;

currentColor[0] = averageColor;
currentColor[1] = averageColor;
currentColor[2] = averageColor;

[self writeColor: currentColor forPixelAtX: x andY: y];

free(currentColor);
}
}
}

-(UIImage*) getProcessedImage
{
// create a UIImage
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(bitmap, imgWidth, imgHeight, bitsPerComponent, bytesPerRow, colorSpace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast);
CGImageRef image = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIImage *resultUIImage = [UIImage imageWithCGImage: image];
CGImageRelease(image);

return resultUIImage;
}

-(void) releaseCurrentImage
{
free(bitmap);
}


@end

我通过以下方式将图像转换为灰度:

    [ [PixelProcessing sharedPixelProcessing] loadWithImage: imageToDisplay.image];
[ [PixelProcessing sharedPixelProcessing] processImage];
imageToDisplay.image = [ [PixelProcessing sharedPixelProcessing] getProcessedImage];
[ [PixelProcessing sharedPixelProcessing] releaseCurrentImage];

为什么运行这么慢?有没有办法获取像素的 RGB 颜色分量的浮点值?我该如何优化它?

谢谢。

最佳答案

您可以让 Quartz 为您进行灰度转换:

CGImageRef grayscaleCGImageFromCGImage(CGImageRef inputImage) {
size_t width = CGImageGetWidth(inputImage);
size_t height = CGImageGetHeight(inputImage);

// Create a gray scale context and render the input image into that
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8,
4*width, colorspace, kCGBitmapByteOrderDefault);
CGContextDrawImage(context, CGRectMake(0,0, width,height), inputImage);

// Get an image representation of the grayscale context which the input
// was rendered into.
CGImageRef outputImage = CGBitmapContextCreateImage(context);

// Cleanup
CGContextRelease(context);
CGColorSpaceRelease(colorspace);
return (CGImageRef)[(id)outputImage autorelease];
}

关于iphone - 转换为灰度 - 太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1311014/

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