iOS:将 6x6 400x300px 图像添加到一张合成图像中
我和我的开发同事正在创建一个用于创建合成图像的 iPhone 应用程序。这个想法是在 6x6 网格中包含 36 个图像。每个原始图像的尺寸为 400x300 像素。因此处理后的最终图像应为 2400x1800px。
免责声明:我自己并不是专门做这个编程的。我的同事程序员不在 SO 上,由于各种原因我不得不去找他。我个人是一名 .Net 开发人员,所以如果我的问题很明显,请原谅我的问题。
现在,显然这会造成内存问题。到目前为止,他的解决方案是尝试将合成绘制到 UIImageView 或 CATiledLayer,并通过截取视图的屏幕截图来保存合成。迄今为止的所有尝试要么由于内存问题而导致应用程序崩溃,要么在合成中产生黑色区域。
我的问题想必很简单。我们如何创建一个大的(屏幕外?)图像,将 36 个部分图像绘制到这个合成中,保存合成,然后将其放入用户可以查看的适当组件中?
编辑:
我的朋友最终自己找到了解决方案。我会将其与已接受的答案一起发布在这里,以便为 SO wiki 做出贡献:)
UIGraphicsBeginImageContext(svPreview.contentSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
CGContextFillRect(ctx, CGRectMake(0, 0, svPreview.contentSize.width, svPreview.contentSize.height));
for(UIImageView *subview in [svPreview subviews]) {
[subview.image drawAtPoint:subview.frame.origin];
}
UIImage *rawImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(rawImage, self, nil, nil);
My fellow developer and I are creating an iPhone app that is creating a composite image. The idea is to have 36 images in a 6x6 grid. Each original image is 400x300px. Hence the final image after processing should be 2400x1800px.
Disclaimer: I'm not doing this programming myself in particular. My fellow programmer is not on SO and for various reasons I'm compelled to ask for him. I'm personally a .Net developer so forgive my question if it's obvious.
Now, apparently this is creating memory issues. His solution thus far has been attempts to draw the composition to an UIImageView or CATiledLayer, and saving the composition by taking a screenshot of the view. All attempts thus far have either crashed the application due to memory issues, or produced black areas in the composition.
My question is presumably simple. How do we create a large (offscreen?) image, draw the 36 partial images to this composition, save the composition, then put it in an appropriate component that can be viewed by the user?
Edit:
My buddy found the solution himself in the end. I'll post it here together with the accepted answer in order to contribute to the SO wiki :)
UIGraphicsBeginImageContext(svPreview.contentSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
CGContextFillRect(ctx, CGRectMake(0, 0, svPreview.contentSize.width, svPreview.contentSize.height));
for(UIImageView *subview in [svPreview subviews]) {
[subview.image drawAtPoint:subview.frame.origin];
}
UIImage *rawImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(rawImage, self, nil, nil);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最明显的机制是 UIScrollView。它是一个用于显示大于屏幕的图像或一组图像的对象,并且具有易于实现的缩放和滚动功能。
您可以在 Apple 的 iOS 滚动视图编程指南。
您只需
contentSize
属性设置为要显示的超大图像的总大小,如果您想制作一张大图像,您可以创建一个与滚动视图的
contentSize
大小相同的大型自定义视图。然后,在自己的网格中绘制每个小图像。最后,添加这个大的自定义视图作为滚动视图的子视图。这是显而易见的解决方案,但它可能会满足您正在寻找的所有功能,并为您提供一些额外的功能。
编辑:滚动视图可能是一个很好的起点,但您可能仍然会遇到内存限制。搜索有关使滚动视图更高效的答案可能会有所帮助。您可能会在此相关问题中找到一些好主意: ScrollView当内存太大时会耗尽内存
编辑2: 管理内存的方法、代码和所有内容都在上述指南中进行了详细介绍。看看 ScrollViewSuite 演示的第三个示例,关于平铺。这应该非常适合您,因为您的图像已经由图块组成。
这个想法是从滚动视图中创建一种表格视图,现在它回收图像图块而不是单元格。滚动视图被子类化,并且一组可重用图块被保留作为其实例变量之一。实现的关键是,在layoutSubviews中,从父视图中删除已移出可见区域的图块,然后回收新可见内容的图块并将其添加为子视图。这样,只有可见的图块才会加载到内存中。
希望这对你有用。
The obvious mechanism would be a UIScrollView. It's an object meant to display an image, or a group of images, that are bigger than the screen, and it comes with easily implementable functionality to zoom and scroll.
You'll find a good primer in Apple's Scroll View's Programming Guide to iOS.
You would just need to
contentSize
property to the total size of the extra large image you want to displayIf you wanted to make the one large image, you could just create a large custom view that's the same size as the scroll view's
contentSize
. Then, draw each smaill image in its own grid. Finally, add this large custom view as the scroll view's subview.This is the obvious solution, but it might do everything you're looking for, and afford you some extra functionality.
Edit: A scroll view may be a good starting point, but you may still hit memory limitations. Searching for answers on making scroll views more efficient may be helpful. You may find some good ideas in this related question: ScrollView runs out of memory when it gets too big
Edit 2: The way to manage memory is detailed, code and all, in the above-mentioned guide. Take a look at the ScrollViewSuite demo's third example, on tiling. That should work perfectly for you since your image is already composed of tiles.
The idea is to make a sort of table view out of the scroll view that now recycles image tiles instead of cells. The scroll view is subclassed and a set of reusable tiles is kept as one of its instance variables. The key to the implementation is, in
layoutSubviews
, to remove from superview the tiles that have moved out of the visible area, then recycle tiles for newly visible content and add them as subview. In this way, only visible tiles are loaded into memory.Hope this works for you.