- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在为 iOS 开发一个通用应用程序,它将动态生成它自己的全屏位图(指向字节缓冲区中 32 位像素数据的指针)。它对触摸事件使用react,并且需要在用户触摸时以响应方式进行绘图(例如缩放/平移)。在我的应用程序开始时,我可以看到我的视网膜 iPad 和 iPod Touch 上的显示缩放了 2 倍。我的代码当前正确创建和显示位图,但分辨率为显示器原始分辨率的 1/2。我可以使用 View 的 nativeBounds 查看原始分辨率,但我想以原始分辨率创建和显示我的位图而不进行任何缩放。我尝试在 drawRect() 方法中更改变换比例,但它没有正常工作。下面是我的 drawRect 代码:
- (void)drawRect:(CGRect)rect
{
UInt32 * pixels;
pixels = (UInt32 *)[TheFile thePointer];
NSUInteger width = [TheFile iScreenWidth];
NSUInteger height = [TheFile iScreenHeight];
NSUInteger borderX = [TheFile iBorderX];
NSUInteger borderY = [TheFile iBorderY];
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef gtx = CGBitmapContextCreate(pixels, width-borderX*2, height-borderY*2, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big);
CGImageRef myimage = CGBitmapContextCreateImage(gtx);
CGContextSetInterpolationQuality(gtx, kCGInterpolationNone); // does this speed it up?
// Create a rect to display
CGRect imageRect = CGRectMake(borderX, borderY, width - borderX*2, height - borderY * 2);
// Need to repaint the background that would show through (black)
if (borderX != 0 || borderY != 0)
{
[[UIColor blackColor] set];
UIRectFill(rect);
}
// Transform image (flip right side up)
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
// Draw the image
CGContextDrawImage(context, imageRect, myimage); //image.CGImage);
CGColorSpaceRelease(colorSpace);
CGContextRelease(gtx);
CGImageRelease(myimage);
} /* drawRect() */
编辑: 下面的答案通过使用 UIImageView 解决了性能问题,通过在 UIImage 的初始化中设置适当的显示比例解决了缩放问题。当 UIImage 比例与显示比例匹配时,它将以设备的原始分辨率以 1:1 的比例显示位图。
最佳答案
您的代码的问题在于,在创建结果图像后,代码将图像绘制到为 drawRect:
配置的当前图形上下文中。绘制图像的是 CPU。这就是为什么需要 70 毫秒。使用 UIImageView
渲染图像或将其设置为层的内容不由 CPU 处理,这样,它由 GPU 处理。 GPU 擅长这样的事情,所以在这种情况下它要快得多。由于 drawRect:
导致 Core Animation
创建一个在这种情况下无用的支持位图,因此您应该创建没有 drawRect:
的图像:
- (UIImage *)drawBackground {
UIImage *output;
UInt32 * pixels;
pixels = (UInt32 *)[TheFile thePointer];
NSUInteger borderX = [TheFile iBorderX];
NSUInteger borderY = [TheFile iBorderY];
NSUInteger width = [TheFile iScreenWidth] - 2 * borderX;
NSUInteger height = [TheFile iScreenHeight] - 2 * borderY;
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGFloat scale = [UIScreen mainScreen].scale;
// create bitmap graphic context
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef gtx = CGBitmapContextCreate(pixels,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrder32Big);
// create image
CGImageRef myimage = CGBitmapContextCreateImage(gtx);
output = [UIImage imageWithCGImage:myimage
scale:[UIScreen mainScreen].scale
orientation:UIImageOrientationUp];
// clean up
CGColorSpaceRelease(colorSpace);
CGContextRelease(gtx);
CGImageRelease(myimage);
return output;
}
当用户触发事件时,假设您使用手势识别器:
- (IBAction)handleTap:(UITapGestureRecognizer *)tap {
UIImage *background = [self drawBackground];
// when background view is an UIImageView
self.backgroundView.image = background;
// self.backgroundView should have already set up in viewDidLoad
// based on your code snippet, you may need to configure background color
// self.backgroundView.backgroundColor = [UIColor blackColor];
// do other configuration if needed...
// when background view is an UIView or subclass of UIView
self.backgroundView.layer.contents = (id)background.CGImage;
// not like UIImageView, the size of background view must exactly equals
// to the size of background image. Otherwise the image will be scaled.
}
我在一个测试项目中写了这个函数:
static UIImage *drawBackground() {
// allocate bitmap buffer
CGFloat scale = [UIScreen mainScreen].scale;
CGRect screenBounds = [UIScreen mainScreen].bounds;
NSUInteger borderWidth = 1 * 2; // width of border is 1 pixel
NSUInteger width = scale * CGRectGetWidth(screenBounds) - borderWidth;
NSUInteger height = scale * CGRectGetHeight(screenBounds) - borderWidth;
NSUInteger bytesPerPixel = 4;
// test resolution begin
// tested on a iPhone 4 (320 x 480 points, 640 x 960 pixels), iOS 7.1
// the image is rendered by an UIImageView which covers whole screen.
// the content mode of UIImageView is center, which doesn't cause scaling.
width = scale * 310;
height = scale * 240;
// test resolution end
UInt32 *pixels = malloc((size_t)(width * height * bytesPerPixel));
// manipulate bitmap buffer
NSUInteger count = width * height;
unsigned char *byte = (unsigned char *)pixels;
for (int i = 0; i < count; i = i + 1) {
byte[0] = 100;
byte = byte + 1;
byte[0] = 100;
byte = byte + 1;
byte[0] = 0;
byte = byte + 2;
}
// create bitmap grahpic context
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef gtx = CGBitmapContextCreate(pixels,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrder32Big);
// create image
CGImageRef myimage = CGBitmapContextCreateImage(gtx);
UIImage *output = [UIImage imageWithCGImage:myimage
scale:scale
orientation:UIImageOrientationUp];
// clean up
CGColorSpaceRelease(colorSpace);
CGContextRelease(gtx);
CGImageRelease(myimage);
free(pixels);
return output;
}
我在 iPhone 4 设备上对其进行了测试。对我来说似乎没问题。这是屏幕截图:
关于ios - 如何在 iOS8 中以原始分辨率显示自制位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27903380/
我正在使用Delphi 7,并且有一个新单元要在我的项目中使用。我已经编译了新的。当我尝试通过将其添加到uses子句在项目中使用此单元时,出现错误,提示未找到.dcu文件。我还尝试将文件的完整路径放在
我有一个项目正在使用 mysql_connect()。 (我无法将其更改为 mysqli) 我收到错误:Call to undefined function mysql_connect() 我已经使用
我现在正在学习 jQuery,第一个“更大”的项目是一个自制的 Accordion /滑动导航。 我的 HTML 代码如下所示: Prologue TEST Projekte
我得到了这段用 JavaScript 编写的代码,但是对于大输入它返回了错误的数字。 它应该用模(mo)计算指数(ex)幂的底数。 我用 C 编写了等效代码并且正在运行。请有人告诉我出了什么问题。 尝
我正在通读 How can I write a power function myself? dan04 给出的答案引起了我的注意,主要是因为我不确定 fortran 给出的答案,但我接受了它并实现了
更新:可能是 jQuery 的 trigger() 在测试中做了一些额外的工作,我打开了一个 issue在 github 上。 ===== 我正在关注 learnQuery构建我的简单 jQuery。
我尝试了各种图库插件,但没有一个适合我的需要。 我有一些标记如下:
为了熟悉 swift 语言和 Cocoa,我决定创建一个小的基数转换,首先从基数 2 到基数 10,然后我想添加一些其他基数,例如 16 和 5。我仍然无法使其正常工作:Running App Vie
我开始编写自己的 vector 类,然后着手重载 = 运算符。我在下面有类似 somevector = someothervector 的代码,尽管我不确定它是否正确,因为我一直在为类似 someve
这里有一些非常相似的问题,但是它们无法帮助我解决这个问题。 另外,我提供了完整的示例代码,因此其他人可能更容易理解。 我制作了一个 vector 容器(出于内存原因,不能使用STL),过去只将oper
我制作了自己的 vector 模板,operator[]一部分: template T& vector::operator[](unsigned int index) { return m_
我们知道我们不应该写 SELECT *;相反,应该写下确实将在业务逻辑中使用的列(例如,在有关整篇文章的一次查询中SELECT blog_title, blog_content,以及SELECT bl
我使用 netbeans,当我准备为应用程序用户的管理创建一个 bean 时,我开始想知道:哪种方式更有益,保留数据库表并在其上应用 EJB,还是创建一个处理与数据库的连接并“手动”进行测试的 bea
所以基本上,作为安全措施(和学习过程),我尝试做的是我自己的“Capthca”系统。发生的情况是我有 20 个“标签”(为简洁起见,下面仅显示一个),每个 ID 都在 1 到 20 之间。我的 jav
我有一个类,它本质上是一个 std::vector具有一些附加功能。类(class)有find(const T& value )返回 value 第一次出现索引的方法或-1: int my::find
最近几天,我一直在尝试使用 Python 进行一些音频开发。 问题是,Mac OSX 不能很好地处理卸载问题。实际上,没有办法卸载任何东西。一旦它出现在您的系统上,您最好祈祷它没有做任何有趣的事情。因
我不明白以下错误消息,但我知道我之前已经在 Linux 上安装了 utf8-light ,没有出现任何问题。有人可以阐明出了什么问题吗?这是 LLVM 问题、GHC 7 问题还是 utf8-light
我是一名优秀的程序员,十分优秀!