在 iOS 4 中保存 UIView 内容,并使用内部图像的实际大小(即放大内容进行保存)
我有一个 UIView,其中有许多 UIImageView 作为子视图。该应用程序在 iOS4 上运行,我使用具有视网膜显示分辨率的图像(即图像加载比例= 2)
我想保存 UIView 的内容...但是...里面有图像的实际大小。即视图的大小为 200x200,内部的图像比例为 2,我想保存 400x400 的结果图像以及所有实际大小的图像。
现在首先想到的是创建一个新的图像上下文并再次加载内部所有图像的比例=1,这应该可以,但我想知道是否有更优雅的方法来做到这一点?似乎需要大量内存和处理器时间来重新加载所有内容,因为它已经完成了......
ps如果有人有答案 - 包括代码会很好
I have an UIView with many UIImageViews as subviews. The app runs on iOS4 and I use images with retina display resolution (i.e. the images load with scale = 2)
I want to save the contents of the UIView ... BUT ... have the real size of the images inside. I.e. the view has size 200x200 and images with scale=2 inside, I'd like to save a resulting image of 400x400 and all the images with their real size.
Now what comes first to mind is to create a new image context and load again all images inside with scale=1 and that should do, but I was wondering if there is any more elegant way to do that? Seems like a waist of memory and processor time to reload everything again since it's already done ...
p.s. if anyone has an answer - including code would be nice
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
将任何 UIView 渲染为图像的实现(也适用于视网膜显示)。
helper.h 文件:
以及 helper.m 文件中的所属实现:
0.0 是比例因子。应用于位图的比例因子。如果指定值 0.0,比例因子将设置为设备主屏幕的比例因子。
QuartzCore.framework 也应该放入项目中,因为我们正在调用图层对象上的函数。
要启用 UIKit 框架上的弱链接,请单击左侧导航器中的项目项,单击项目目标 ->构建阶段 ->链接二进制文件并在 UIKit 框架上选择“可选”(弱)类型。
这是库,具有 UIColor、UIImage、NSArray、NSDictionary 等类似扩展。
Implementation for rendering any UIView to image (working also for retina display).
helper.h file:
and belonging implementation in helper.m file:
0.0 is the scale factor. The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
QuartzCore.framework also should be put into the project because we are calling function on the layer object.
To enable weak link on UIKit framework, click on the project item in left navigator, click the project target -> build phases -> link binary and choose "optional" (weak) type on UIKit framework.
Here is library with similar extensions for UIColor, UIImage, NSArray, NSDictionary, ...
我已经执行了这样的操作,将 MKMapView 中的引脚保存为 PNG 文件(在视网膜显示中): MKPinAnnotationView:是否有超过三种颜色可用?
以下是执行
UIView
保存的关键部分的摘录(theView
) 使用其视网膜定义:I've performed such thing to save the pins from the MKMapView as a PNG file (in retina display): MKPinAnnotationView: Are there more than three colors available?
Here's an extract of the crucial part that performs the saving of a
UIView
(theView
) using its retina definition:关键是 UIGraphicsBeginImageContextWithOptions 的第三个参数是比例,它决定了图像最终如何写出。
如果您始终想要真实的像素尺寸,请使用 [[UIScreen mainScreen] scale] 获取屏幕的当前比例:
UIGraphicsBeginImageContextWithOptions(viewSizeInPoints, YES, [[UIScreen mainScreen] scale]);
如果您在iPhone4上使用scale=1.0,您将获得尺寸以点为单位的图像,并且结果是根据真实像素数按比例缩小的。如果您手动将图像写入 640x960 尺寸(例如:将像素作为第一个参数传递),它实际上是按比例缩小的图像,然后按比例放大,看起来与您想象的一样糟糕。
The key is that the third parameter to UIGraphicsBeginImageContextWithOptions is the scale, which determines how the image will ultimately be written out.
If you always want the real pixel dimensions, use [[UIScreen mainScreen] scale] to get the current scale of the screen:
UIGraphicsBeginImageContextWithOptions(viewSizeInPoints, YES, [[UIScreen mainScreen] scale]);
If you use scale=1.0 on iPhone4, you will get an image with its dimension in points and the result is scaled down from the true pixel count. If you manually write the image out to a 640x960 dimension (eg: passing pixels as the first parameter), it will actually be the scaled-down image that is scaled back up which looks about as terrible as you imagine it would look.
难道您不能以所需的大小创建一个新的图形上下文,使用 CGAffineTransform 将其缩小,渲染根 UIView 的根层,将上下文恢复到原始大小并渲染图像吗?还没有尝试过对视网膜内容进行此操作,但这似乎对于在 UIImageViews 中按比例缩小的大图像效果很好...
类似:
Couldn't you just create a new graphics context at the desired size, use a CGAffineTransform to scale it down, render the root UIView's root layer, restore the context to the original size and render the image? Haven't tried this for retina content, but this seems to work well for large images that have been scaled down in UIImageViews...
something like:
导入QuartzCore(单击主项目,构建阶段,导入)并在需要的地方添加:
我的imageViews是属性,如果不是,请忽略
.self
并将imageViews作为参数传递到函数中,然后在新的UIGraphicsCurrentContext
中对两个图像调用renderInContext
Import QuartzCore (Click main project, Build Phases, import) and where you need it add:
My imageViews are properties, if your are not, ignore the
.self
and pass the imageViews into the function as parameters, then callrenderInContext
on the two images in a newUIGraphicsCurrentContext