gpt4 book ai didi

objective-c - 快速替代 drawInRect

转载 作者:搜寻专家 更新时间:2023-10-30 19:49:06 25 4
gpt4 key购买 nike

以高帧率将图像渲染和缩放到表面的最快方法是什么?

我正在使用 drawRect 以大约 30FPS 的速度绘制(缩放)NSBitmapImageRep,但它使用了大量的 CPU。

将 NSBitmapImageRep 中的像素设置为 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。以高帧率缩放和绘制图像的最快方法是什么?源图像应该是我可以直接设置像素的图像,例如通过获取位图数据指针。

如果我将 NSBitmapImageRep 转换为 CIImage 并使用 [ciImage drawInRect] 进行绘制,那么速度会提高大约 10%。如果我绘制到 NSOpenGLView 而不是 NSView,它又快了大约 10%,但 scale/drawInRect 仍然占用了大量 CPU 时间。

最佳答案

首先,您应该删除 NSGraphicsContext 的保存和恢复,因为 -[NSImageRep drawInRect:] 方法本身会执行此操作。请参阅“Cocoa 绘图图形上下文”:

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

顺便说一句:如果您将 jpeg 图像读入 NSBitmapImageRep,那么这些 imageReps 总是有 3 个字节的像素加上一个填充字节。为什么会浪费存储空间?这样做有充分的理由!

关于objective-c - 快速替代 drawInRect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24442017/

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