1

我正在使用[uiImage drawAtPoint]绘制新图像。但事实证明颜色变了。我的原始图像uiImage是红色的,而生成的图像newImage是蓝色的。这是我的代码:

UIImage* uiImage = [UIHelper loadImage:fileName];
NSString *text = [ApplicationSettings instance].user.name;
UIGraphicsBeginImageContext(uiImage.size);
[uiImage drawAtPoint: CGPointZero];
[text drawAtPoint: CGPointMake(10, 10) withFont: [UIFont systemFontOfSize: 12]];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return [Texture createTexture: newImage];

并在[Texture createTexture]

+ (Texture*) createTextureWithImage:(UIImage*)image {
    Texture* tex = [[[Texture alloc] init] autorelease];
    if ([tex loadImage:image])
        return tex;
    else {
        NSLog(@"Failed to load image %@", image);
        return nil;
    }
}

- (BOOL)loadImage:(UIImage *)image {
    BOOL ret = NO;

    if (image) {
        // Get the inner CGImage from the UIImage wrapper
        CGImageRef cgImage = image.CGImage;

        // Get the image size
        width = CGImageGetWidth(cgImage);
        height = CGImageGetHeight(cgImage);

        // Record the number of channels
        channels = CGImageGetBitsPerPixel(cgImage)/CGImageGetBitsPerComponent(cgImage);

        // Generate a CFData object from the CGImage object (a CFData object represents an area of memory)
        CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));

        // Copy the image data for use by Open GL
        ret = [self copyImageDataForOpenGL: imageData];
        CFRelease(imageData);
    }

    return ret;
}

而在[texture copyImageDataForOpenGL]

- (BOOL)copyImageDataForOpenGL:(CFDataRef)imageData {
    if (pngData) {
        free(pngData);
    }

    pngData = (unsigned char*)malloc(width * height * channels);
    const int rowSize = width * channels;
    const unsigned char* pixels = (unsigned char*)CFDataGetBytePtr(imageData);

    // Copy the row data from bottom to top
    for (int i = 0; i < height; ++i) {
        memcpy(pngData + rowSize * i, pixels + rowSize * (height - 1 - i), width * channels);
    }

    return YES;
}

我猜生成的图像使用 RGB 顺序,而原始图像使用相反的顺序。这是因为白色和黑色保持不变。

编辑

我正在使用 OpenGL ES 来渲染这个纹理。

return [Texture createTexture: uiImage];而不是return [Texture createTexture: newImage]完美地工作,但我想在uiImage.

我已经测试过UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil);,保存的图像是正确的。

我打印了CGImageGetBitmapInfo(uiImage.CGImage))and CGImageGetBitmapInfo(newImage.CGImage),它们不一样!

4

1 回答 1

1

这是我当前和正确的版本copyImageDataForOpenGL

- (BOOL)copyImageDataForOpenGL:(CGImageRef)image {
    if (pngData) {
        free(pngData);
    }

    pngData = (GLubyte*)malloc(width * height * channels);
    const int rowSize = width * channels;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSUInteger bytesPerPixel = channels;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(pngData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
    CGContextClearRect(context, CGRectMake(0, 0, width, height));
    CGContextTranslateCTM(context, 0,0);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);

    [ARRenderer flipRGBData: pngData bytesPerRow:bytesPerRow height:height];
    return YES;
}

其中[ARRenderer flipRGBData]定义为

+ (void)flipRGBData:(GLubyte*)data bytesPerRow:(int)bytesPerRow height:(int)height {
    GLubyte* swp = (GLubyte*)malloc(bytesPerRow);
    for (int h = 0; h < height / 2; h++) {
        memcpy(swp, data + (height - 1 - h) * bytesPerRow, bytesPerRow);
        memcpy(data + (height - 1 - h) * bytesPerRow, data + h * bytesPerRow, bytesPerRow);
        memcpy(data + h * bytesPerRow, swp, bytesPerRow);
    }
    free(swp);
}
于 2013-03-08T16:55:27.720 回答