以高帧速率渲染图像并将图像缩放到曲面的最快方法是什么?
我正在绘制(使用缩放)一个NSBitmapImageRep,使用drawRect在~30FPS,但它使用了大量的CPU。
用于设置NSFitmapImageRep中30FPS像素的示例代码:
NSInteger x, y;
unsigned char *imgptr = nsBitmapImageRepObj.bitmapData;
unsigned char *ptr;
NSInteger rowBytes = nsBitmapImageRepObj.bytesPerRow;
for (y = 0; y < nsInputFrameRect.size.height; y++) {
ptr = imgptr + (y * rowBytes);
for (x = 0; x < nsInputFrameRect.size.width; x++) {
*ptr++ = 1; // R
*ptr++ = 2; // G
*ptr++ = 3; // B
}
}
[self setNeedsDisplay:YES];
抽签发生在30FPS:
- (void)drawRect:(NSRect)pRect {
[NSGraphicsContext saveGraphicsState];
[nsBitmapImageRepObj drawInRect:pRect];
[NSGraphicsContext restoreGraphicsState];
} // end drawRect
NSBitmapImageRep上的drawInRect使用了大量的CPU。以高帧速率缩放和绘制图像的最快方法是什么?源图像应该是我可以直接设置像素的图像,例如通过获取bitmapData指针。
如果我将NSBitmapImageRep转换为CIImage并使用[ciImage drawInRect]进行绘制,那么它的速度提高了大约10%。如果我绘制NSOpenGLView而不是NSView,它再次快10%,但是scale / drawInRect仍占用大量的CPU时间。
答案 0 :(得分:0)
首先,您应该删除保存并恢复NSGraphicsContext
,因为-[NSImageRep drawInRect:]
方法会自行执行此操作。请参阅&#34; Cocoa绘图图形上下文&#34;:
Important: Saving and restoring the current graphics state is a relatively expensive operation that should done as little as possible.
下一点是像素数据的结构:每个样本8位,每个像素3个样本,这意味着每像素24位。这是非常硬件(GPU?)不友好,因为32位值比24位值更快处理。有一种简单的方法可以使像素处理更好(更快):使用4个字节而不是3个:为每个像素添加填充字节,这不会损害图像!此填充字节不是图像的一部分,而只是存储像素的存储的一部分,并且不用于任何绘图操作。只是在这里使像素操作更快。因此,请在NSBitImageRep
:
bitsPerSample:8
samplesPerPixel:3
hasAlpha:NO
isPlanar:NO // must be meshed
bytesPerRow:0 // let the system do it
bitsPerPixel:32 // <-- important !!
因此您的代码必须修改:
*ptr++ = 3; // B
*ptr++ = 123; // new!! value is unimportant
BTW:如果你将jpeg-image读入NSBitmapImageRep
,那么这些imageReps总是有3个字节的像素加上一个填充字节。为什么这会浪费存储?有充分的理由这样做!