c++ - 如何从自定义数据流编写 CoreGraphics CGImageRef?

标签 c++ objective-c core-graphics quartz-graphics

我希望最终得到的是一个 Core Graphics CGImageRef,它是通过重写的 -(void)drawRect:(CGRect)rect 方法绘制到屏幕上的。这是我到目前为止所得到的。

- (void)drawRect:(CGRect)rect
{
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    const CGFloat _x = CGRectGetMinX(rect);
    const CGFloat _y = CGRectGetMinY(rect);
    const CGFloat _w = CGRectGetWidth(rect);
    const CGFloat _h = CGRectGetHeight(rect);

    const CGFloat scale = [[UIScreen mainScreen] scale];

    const int pixelsWide = (_w * scale);
    const int pixelsHigh = (_h * scale);

    const size_t colorValues = 4;
    const int rawMemorySize = (pixelsWide * pixelsHigh * colorValues);

    // raw pixel data memory
    UInt8 pixelData[rawMemorySize];

    // fill the raw pixel buffer with arbitrary gray color for test

    for(size_t ui = 0; ui < rawMemorySize; ui++)
    {
        pixelData[ui] = 255; // black
    }

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CFDataRef rgbData = CFDataCreate(NULL, pixelData, rawMemorySize);
    CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);

    CGImageRef rgbImageRef = CGImageCreate(pixelsWide, pixelsHigh, 8, (colorValues * colorValues), (pixelsWide * colorValues), colorspace, kCGBitmapByteOrderDefault, provider, NULL, true, kCGRenderingIntentDefault);

    CFRelease(rgbData);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorspace);

    //Draw the bitmapped image
    CGContextDrawImage(currentContext, CGRectMake(_x, _y, pixelsWide, 64), rgbImageRef);
    CGImageRelease(rgbImageRef);
}

我在 for 循环中抛出 EXC_BAD_ACCESS 错误。

我想我已经很接近了,但我不太确定。有什么想法可能是罪魁祸首吗?预先感谢您:)

最佳答案

还有一些需要注意的事情。

drawRect 的 rect 参数只是脏矩形,它可能小于 self.bounds。使用 self.bounds 除非您的代码经过优化以仅绘制脏矩形。

在堆栈上分配 pixelData 数组是一个坏主意,并且可能是导致错误的原因。这完全取决于视野有多大。我怀疑 AaronGolden 使用的 View 比您小,因此没有任何问题。更安全的做法是 calloc 数组,并在使用完毕后将其释放。请注意,calloc 会将数组清除为透明黑色。

这是我过去用来做此类事情的一些示例代码。即使像素数组是使用 calloc 创建的,您仍然可以像标准数组一样访问它(例如,pixels[100] = 0xff0000ff; 完全有效)。但是,出于性能原因,我通常使用指针来访问各个像素。

const CGFloat scale = [[UIScreen mainScreen] scale];
int width  = self.bounds.size.width  * scale;
int height = self.bounds.size.height * scale;

uint32_t *pixels = calloc( width * height, sizeof(uint32_t) );
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate( pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast );

uint8_t *bufptr = (uint8_t *)pixels;
for ( int y = 0; y < height; y++)
{
    for ( int x = 0; x < width; x++ )
    {
        bufptr[0] = redValue;
        bufptr[1] = greenValue;
        bufptr[2] = blueValue;
        bufptr[3] = alphaValue;

        bufptr += 4;
    }
}

CGImageRef newCGImage = CGBitmapContextCreateImage( context );
CGContextRelease( context );
CGColorSpaceRelease( colorSpace );
free( pixels );

关于c++ - 如何从自定义数据流编写 CoreGraphics CGImageRef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24792899/

相关文章:

c++ - 如何使用 scons 运行 gtest

c++ - 在protobuf中,copyFrom优先于赋值吗?

iphone - CGContext 中的 alpha 像素数

ios - CGContextStrokePath使用线条颜色

ios - 使用 Swift 的 Core Graphics/Quartz Core resizing 从较小尺寸调整到较大尺寸

c++ - 将整数表示为字节

c++ - 使用高斯消元的文本文件的逆矩阵。 C++

objective-c - 无法在Xcode中更改产品名称

ios - 无法删除 subview Controller

ios - 如何在Objective C中通过UIView获取UIAlertController?