问题描述
我试图做的这将是类似于刷子或层或Photoshop的一个删节版的iPhone一个位图编辑器应用程序。我希望能够支持1000×1000分辨率的图像,约4层,如果可能的。
I'm trying to make a bitmap editor app for the iphone which would be similar to Brushes or Layers or a cut-down version of Photoshop. I'd like to be able to support 1000x1000 resolution images with about 4 layers if possible.
我想设计我撤销/重做系统之前,我写太多code和我有真正的问题想出由于移动设备的限制,一个很好的解决方案,事实上,位图编辑器操作通常是破坏性的。最常见的撤销/重做的设计,我知道的是:
I'm trying to design my undo/redo system before I write too much code and I'm having real issues coming up with a good solution because of the limitations of a mobile device and the fact that bitmap editor operations are usually destructive. The most common undo/redo designs I know of are:
-
使用命令模式。你存储的初始状态和命令用于转化这对当前的状态。要撤消,重新加载初始状态和重播,除了最后一个所有的命令。
Use the command pattern. You store the initial state and the commands used to transform this to the current state. To undo, you reload the initial state and replay all the commands except for the last one.
使用Memento模式。每次操作之后,存储足够的信息,以便能够恢复该操作。
Use the memento pattern. After each operation, you store enough information to be able to revert that operation.
我可以预见到的问题是:
The problems I foresee are:
-
命令模式:经过500的编辑操作,该怎么办,我想撤消最后一个?加载初始状态和应用499可能是耗时的,特别是如果其中一些是像如昂贵的东西应用模糊滤镜。我不喜欢毁灭的方式采取了不同的量在不同情况下的时间。
Command pattern: What do I do after 500 edit operations and I want to undo the last one? Loading the initial state and applying 499 could be time consuming especially if some of these are costly things like e.g. applying blur filters. I don't like the way undoing takes a different amount of time under different scenarios.
备忘录模式:保存已修改位图的部分需要大量的内存。缓存这些位图到磁盘上可能会很慢,以及(所以我可能有麻烦高速缓存,如果用户正在大量快速编辑的位图),我不知道电池的使用产生影响。
Memento pattern: Saving the parts of the bitmap that were modified takes a lot of memory. Caching these bitmaps to disk can be slow as well (so I might have trouble caching the bitmaps if the user is making lots of fast edits) and I'm not sure about the battery usage implications.
唯一的解决方案,我能想到的是:
The only solutions I can think of are:
-
使用命令模式,纪念品模式,其中,每10个命令左右或昂贵的手术后,整个状态也被保留(这为您提供免费的自动保存功能)。要撤消,我重装最接近的快照,然后重播命令。我宁愿虽然避免这种复杂性。
Use the command pattern and memento pattern where, every 10 commands or so or after an expensive operation, the whole state is also saved (which gives you an autosave feature for free). To undo, I reload the closest snapshot and then replay the commands. I'd rather avoid this complexity though.
使用Memento模式,并强制用户等待位图缓存。这是不是太糟糕,如果我建立这个时候到如等待一个过滤器以应用于但它不会使笔触之间很好地工作。
Use the memento pattern and force the user to wait for the bitmaps to be cached. This isn't too bad if I build this time into e.g. waiting for a filter to apply but it doesn't work well between making brush strokes.
是建议?我很想知道一些现有的应用程序是如何做到这一点。
Are advice? I'd be interested to know how some existing apps do this.
我能想到的各种怪异的杂种以上,但它们都有明显的问题的。所有我能想到做的是现场有一些问题或危及应用程序,以使问题更简单(如减少最大的位图大小的尺寸)。我注意到,几个应用程序具有相当低的最高位图的大小和层的限制。
I can think of all sorts of weird hybrids of the above but they all have obvious problems. All I can think to do is live with some of these problems or compromise the app to make the problem simpler (e.g. reduce the size of the maximum bitmap size). I have noticed that several apps have quite low maximum bitmap sizes and layer limits.
推荐答案
每个检查站位内存映射在iOS设备上的Flash存储器的速度足以支持撤销/重做操作的大位图。使用mmap系统调用,我的内存映射1024×768 ABGR位图轻松,使用precious DRAM救了我的计划。我不知道你怎么想抽象的撤销/重做模式,但方式,以避免任何高开销的复制操作是有指针的撤销和重做位图交换各自撤销/重做。您已经指定了多个撤消水平,但我敢打赌,你可以逃脱一些指针交换(我从一些失眠,现在,想要证明指针交换证明太多 - 这是一些pretty的垃圾伪code)。
Checkpoint each bitmap with memory mappingThe flash memory on iOS devices is fast enough to support undo/redo operations on large bitmaps. Using the mmap system call, I memory mapped 1024x768 ABGR bitmaps with ease, saving my program from using precious DRAM. I don't know how you would like to abstract the undo/redo patterns but the way to avoid any high-overhead copy operations is to have the pointers for undo and redo bitmaps swap each undo/redo. You have specified more than one undo level, but I bet you can get away with some pointer swapping (I am suffering from some insomnia right now and trying to demonstrate the pointer swapping proved too much--it was some pretty garbage psuedocode).
另外,我不建议你标记的网页mmap'd作为F_NOCACHE。这是preferable有iOS的高速缓存写入位图DRAM原因:
Also, I would not recommend marking your mmap'd pages as F_NOCACHE. It is preferable to have iOS cache writes to the bitmap in DRAM because:
- 在它的速度更快,如果你不冲水闪烁
- 在闪存设计用于写入固定数量 - 这不是很好烧坏用户的闪存(我认为这需要500万的数量级上的某个地方,在iOS设备的质量闪存写入)
- 我相信iOS的是在内存管理上,它将取消映射缓存的写入操作,并在内存危机刷新他们足够的侵略性(我从来不关心不够,检查,虽然)
喊出约翰·卡马克的提示关闭了的iDevice闪存是相当快的(他使用F_NOCACHE,虽然得到predictable读取性能)。
Shout out to John Carmack for the tip-off that the iDevice Flash memory is quite fast (He uses F_NOCACHE, though, to get predictable read performance).
请注意,我必须调用MMAP对FD之前,使文件是实际的位图的大小。不要去坚果内存映射100位图,虽然(开个玩笑 - DO IT!)我的意思是,有多少索马里发展事务处可以在用户执行?他们是弱,他们的手指累按钮糖化的几秒钟后。
Note that I had to make the file be the size of the actual bitmap before calling mmap on the fd. Don't go nuts memory mapping 100 bitmaps, though (just kidding--DO IT!) I mean, how many undos can a user perform? They are weak and their fingers get tired after mere seconds of button-mashing.
这篇关于快速撤销工具位图编辑器应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!