vImage_Buffer 没有渲染到 CGContext,为什么?
vImage_Buffer not rendering into CGContext, Why?
下面的代码尝试获取图像,将其组件提取到 vImage_Buffer 中,然后循环遍历此缓冲区并获取每个组件并通过填充 outputBuffer 反转红色和蓝色通道。之后,我想获取生成的 outputBuffer 并从中创建一个 UIImage。
尽管以下代码编译并运行良好,但 outputImage 是空白的,我没有收到任何错误。
CGFloat inputImageScale = inputImage.scale;
CGSize outputImageSizeInPoints = inputImage.size;
CGRect outputImageRectInPoints = { CGPointZero, outputImageSizeInPoints };
UIGraphicsBeginImageContextWithOptions(outputImageRectInPoints.size, NO, inputImageScale);
CGContextRef outputContext = UIGraphicsGetCurrentContext();
CGContextScaleCTM(outputContext, 1.0, -1.0);
CGContextTranslateCTM(outputContext, 0, -outputImageRectInPoints.size.height);
vImage_Buffer originalBuffer;
vImage_Buffer *inputBuffer;
vImage_Buffer *outputBuffer;
vImage_CGImageFormat format = {
.bitsPerComponent = 8,
.bitsPerPixel = 32,
.colorSpace = NULL,
// (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
// requests a BGRA buffer.
.bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little,
.version = 0,
.decode = NULL,
.renderingIntent = kCGRenderingIntentDefault
};
vImage_Error e = vImageBuffer_InitWithCGImage(&originalBuffer, &format, NULL, inputImage.CGImage, kvImagePrintDiagnosticsToConsole);
if (e != kvImageNoError)
{
NSLog(@"*** error: vImageBuffer_InitWithCGImage returned error code %zi for inputImage: %@", e, inputImage);
UIGraphicsEndImageContext();
return nil;
}
inputBuffer = &originalBuffer;
vImageBuffer_Init(outputBuffer, originalBuffer.height, originalBuffer.width, format.bitsPerPixel, kvImageNoFlags);
Byte *data = (Byte*)inputBuffer->data;
for(vImagePixelCount i = 0; i < inputBuffer->width + inputBuffer->height; i+=4) {
Byte B = (Byte)data[i];
Byte G = (Byte)data[i + 1];
Byte R = (Byte)data[i + 2];
Byte A = (Byte)data[i + 3];
NSLog(@"1: (%d) %d, %d, %d, %d", i, R,G,B,A);
((Byte*)outputBuffer->data)[i] = R;
((Byte*)outputBuffer->data)[i + 1] = G;
((Byte*)outputBuffer->data)[i + 2] = B;
((Byte*)outputBuffer->data)[i + 3] = A;
}
CGImageRef effectCGImage = vImageCreateCGImageFromBuffer(outputBuffer, &format, &cleanupBuffer, NULL, kvImageNoFlags, &e);
// draw effect image
CGContextSaveGState(outputContext);
CGContextDrawImage(outputContext, outputImageRectInPoints, effectCGImage);
CGContextRestoreGState(outputContext);
// Cleanup
CGImageRelease(effectCGImage);
// Output image is ready.
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
那么,上面的代码有什么问题呢?
P.S.: 我知道我可以使用一些 vImage_ 函数来反转通道,但这不是我想要达到的目的。我想要实现的是通过一个一个地改变每个像素来改变图像。最终我的目的是创建一个 DisplacementMapFilter(根据提供的地图转换图像像素)。
解决了问题。这种情况下的特殊问题是:
for(vImagePixelCount i = 0; i < (inputBuffer->width * inputBuffer->height * 4); i+=4)
我只是在缓冲区的一小部分中循环。现在我正在遍历整个缓冲区。
下面的代码尝试获取图像,将其组件提取到 vImage_Buffer 中,然后循环遍历此缓冲区并获取每个组件并通过填充 outputBuffer 反转红色和蓝色通道。之后,我想获取生成的 outputBuffer 并从中创建一个 UIImage。
尽管以下代码编译并运行良好,但 outputImage 是空白的,我没有收到任何错误。
CGFloat inputImageScale = inputImage.scale;
CGSize outputImageSizeInPoints = inputImage.size;
CGRect outputImageRectInPoints = { CGPointZero, outputImageSizeInPoints };
UIGraphicsBeginImageContextWithOptions(outputImageRectInPoints.size, NO, inputImageScale);
CGContextRef outputContext = UIGraphicsGetCurrentContext();
CGContextScaleCTM(outputContext, 1.0, -1.0);
CGContextTranslateCTM(outputContext, 0, -outputImageRectInPoints.size.height);
vImage_Buffer originalBuffer;
vImage_Buffer *inputBuffer;
vImage_Buffer *outputBuffer;
vImage_CGImageFormat format = {
.bitsPerComponent = 8,
.bitsPerPixel = 32,
.colorSpace = NULL,
// (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
// requests a BGRA buffer.
.bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little,
.version = 0,
.decode = NULL,
.renderingIntent = kCGRenderingIntentDefault
};
vImage_Error e = vImageBuffer_InitWithCGImage(&originalBuffer, &format, NULL, inputImage.CGImage, kvImagePrintDiagnosticsToConsole);
if (e != kvImageNoError)
{
NSLog(@"*** error: vImageBuffer_InitWithCGImage returned error code %zi for inputImage: %@", e, inputImage);
UIGraphicsEndImageContext();
return nil;
}
inputBuffer = &originalBuffer;
vImageBuffer_Init(outputBuffer, originalBuffer.height, originalBuffer.width, format.bitsPerPixel, kvImageNoFlags);
Byte *data = (Byte*)inputBuffer->data;
for(vImagePixelCount i = 0; i < inputBuffer->width + inputBuffer->height; i+=4) {
Byte B = (Byte)data[i];
Byte G = (Byte)data[i + 1];
Byte R = (Byte)data[i + 2];
Byte A = (Byte)data[i + 3];
NSLog(@"1: (%d) %d, %d, %d, %d", i, R,G,B,A);
((Byte*)outputBuffer->data)[i] = R;
((Byte*)outputBuffer->data)[i + 1] = G;
((Byte*)outputBuffer->data)[i + 2] = B;
((Byte*)outputBuffer->data)[i + 3] = A;
}
CGImageRef effectCGImage = vImageCreateCGImageFromBuffer(outputBuffer, &format, &cleanupBuffer, NULL, kvImageNoFlags, &e);
// draw effect image
CGContextSaveGState(outputContext);
CGContextDrawImage(outputContext, outputImageRectInPoints, effectCGImage);
CGContextRestoreGState(outputContext);
// Cleanup
CGImageRelease(effectCGImage);
// Output image is ready.
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
那么,上面的代码有什么问题呢?
P.S.: 我知道我可以使用一些 vImage_ 函数来反转通道,但这不是我想要达到的目的。我想要实现的是通过一个一个地改变每个像素来改变图像。最终我的目的是创建一个 DisplacementMapFilter(根据提供的地图转换图像像素)。
解决了问题。这种情况下的特殊问题是:
for(vImagePixelCount i = 0; i < (inputBuffer->width * inputBuffer->height * 4); i+=4)
我只是在缓冲区的一小部分中循环。现在我正在遍历整个缓冲区。