2010-10-10 3 views
11

Tôi đang cố gắng viết trình chỉnh sửa bitmap cho thiết bị di động (ví dụ: phiên bản giới hạn của Photoshop). Tài liệu của người dùng bao gồm ~ 4 bitmap có kích thước khoảng 1000x500.Hoàn tác/hoàn tác nhanh cho trình chỉnh sửa bitmap khi bộ nhớ bị hạn chế?

Tôi muốn một hệ thống hoàn tác/làm lại mạnh mẽ và hiệu quả đơn giản nhất có thể. Tôi đang nhắm tới khoảng 0,2 giây để hoàn tác hoặc làm lại chỉnh sửa. Tôi đang tìm một số phản hồi về cách tiếp cận dự định hiện tại của tôi hoặc cho một số ý tưởng mới mà tôi có thể sử dụng. Tôi nghĩ rằng những gì tôi có là quá phức tạp vì vậy tôi thận trọng về việc tiếp tục để chỉ biết rằng đó là điều tốt nhất tôi có thể làm sẽ tốt.

Tôi đã thử nghiệm với các kết hợp sử dụng mẫu Command và mẫu Memento cho hệ thống hoàn tác/làm lại của tôi. Một số kết luận mà tôi đã đưa ra cho đến nay là:

  1. Tôi không có đủ bộ nhớ và không thể ghi bộ nhớ vào đĩa đủ nhanh để sử dụng bộ lưu trữ để hỗ trợ thao tác "không thực hiện" trên lệnh trước đó nhiều tình huống ví dụ nếu người dùng thực hiện một vài nét vẽ riêng lẻ một cách nhanh chóng, tôi sẽ không thể lưu trữ các ảnh bitmap đại diện cho những gì người dùng vẽ lên mà không khiến người dùng chờ chúng được lưu.

  2. Nếu tôi khôi phục tài liệu về trạng thái ban đầu và phát lại tất cả các lệnh ngoại trừ lệnh cuối cùng để hoàn tác, điều này quá chậm sau một số lệnh khiêm tốn, ví dụ: phát lại 10 nét vẽ hoặc 5 vết nhòe mất ~ 1 giây quá chậm chạp.

  3. Tôi có thể lấy xung quanh điểm trước đó bằng cách lưu toàn bộ tài liệu trong nền theo định kỳ vào đĩa và khôi phục đến điểm kiểm tra này trước khi phát lại lệnh. Để hoàn tác hơn nữa so với trạm kiểm soát cuối cùng, chúng tôi sẽ tải lại điểm kiểm tra trước và thực hiện lại các lệnh.

Cách tiếp cận 2 với 3 hoạt động OK ngoại trừ lưu toàn bộ tài liệu chậm hơn và chậm hơn khi thêm nhiều lớp và nó đã chậm với 4 bitmap (~ 5 - 10 giây chờ). Do đó, tôi cần phải sửa đổi 3 để tôi chỉ lưu những gì đã thay đổi kể từ lần trước.

Vì nhiều lệnh chỉ hoạt động trên một lớp, nên chỉ lưu các lớp đã được sửa đổi kể từ điểm kiểm tra cuối cùng. Ví dụ, lệnh stack của tôi có thể trông như thế này nếu tôi có 3 lớp ban đầu, nơi tôi đã chỉ ra nơi các trạm kiểm soát có thể được lưu.

(Checkpoint1: Save layer 1, 2 and 3.) 
Paint on layer 1 
Paint on layer 1 
(Checkpoint2: Save layer 1. Reuse saved layers 2 and 3 from Checkpoint1.) 
Paint on layer 2 
Paint on layer 2 
(Checkpoint3: Save layer 2. Reuse saved layers 1 and 3 from Checkpoint2.) 
Paint on layer 3 
Paint on layer 3 
Flip layer 3 horizontally. 
(Checkpoint4: Save layer 3. Reuse saved layers 1 and 2 from Checkpoint3.) 
Resize layer 1, 2 and 3. 
(Checkpoint5: Save layer 1, 2, 3.) 

Trong khi chỉnh sửa, tôi theo dõi các lớp nào đã được sửa đổi kể từ điểm kiểm tra trước đó. Khi tôi khôi phục lại một trạm kiểm soát, tôi chỉ khôi phục các lớp đã thay đổi, ví dụ: để khôi phục Checkpoint4 sau khi sửa đổi lớp 2 và 3, tôi tải lại các bản sao lưu của lớp 2 và 3 từ đĩa. Khi thêm một trạm kiểm soát, tôi chỉ lưu các lớp đã được sửa đổi cho đến nay. Tôi có thể làm cho tất cả điều này chủ yếu là tự động trừ khi cần phải có chỗ trong giao diện của tôi, nơi người dùng buộc phải đợi cho các trạm kiểm soát được lưu vì tôi chỉ có thể giữ khoảng 1 bản sao tạm thời của một lớp trong bộ nhớ tại một thời điểm.

Bạn nghĩ sao? Nó phức tạp hơn nhiều so với tôi muốn nhưng tôi không thể nhìn thấy bất kỳ cách nào khác. Có bất kỳ mẫu hữu ích nào khác mà tôi có thể sử dụng để làm cho cuộc sống của tôi dễ dàng hơn không?

Trả lời

1

sau này có thể có ích cho các lớp và lùi lại bộ đệm sử dụng hình ảnh:

  • Giữ hình ảnh mới nhất như một hình ảnh
  • phiên bản trước được lưu trữ dưới dạng xor với phiên bản tiếp theo và sau đó (giả sử không phải mọi thứ thay đổi hoặc thay đổi trong cách thức tương tự) nén sử dụng một thuật toán nén đơn giản (như mã hóa chạy dài)

này có những ưu điểm sau

  • các phiên bản trước có thể dễ dàng hợp nhất (xho chúng lại với nhau).

này có thể không làm việc tốt với:

  • điều chỉnh màu sắc (màu sắc, độ sáng vv)
  • phối hợp biến đổi (cây trồng, kỹ xảo, vv)
+0

Cảm ơn. Điều này sẽ giúp tiết kiệm các trạm kiểm soát nhanh hơn một chút và hiệu quả về không gian hơn nhưng giúp khôi phục các điểm kiểm tra chậm hơn một chút vì tôi cần tải và kết hợp nhiều điểm kiểm tra để khôi phục trạng thái trước đó. Tôi muốn đánh giá cao một số ý kiến ​​về tổng thể của tôi undo/redo chương trình mặc dù và làm thế nào nó có thể được thực hiện đơn giản hơn mặc dù. – memcom

1

Một cách tiếp cận là để giữ cho 'khung' nhất định làm khung hoàn chỉnh và các khung khác là lệnh cần thiết để tạo khung từ khung trước đó. Bạn ám chỉ điều này trong # 2 của bạn. Nó có thể hữu ích để giữ một số khung hình trong bộ nhớ.

Một thủ thuật có thể giúp cân bằng hiệu suất với không gian/thời gian có sẵn để giữ khung hoàn chỉnh là loại bỏ một phần nhỏ của khung cũ, vì vậy tại bất kỳ thời điểm nào bạn có thể hoàn tác trạng thái từ ví dụ: 1, 2, 4, 8, 16, 32 và 64 hoạt động trước đây. Việc hoàn tác một hoặc hai thao tác sẽ yêu cầu chỉ cần đọc khung. Việc hoàn tác ba sẽ yêu cầu đọc một trạm kiểm soát và lặp lại một thao tác. Hoàn tác năm sẽ yêu cầu đọc một trạm kiểm soát và lặp lại ba hoạt động. Hoàn tác ba mươi ba sẽ yêu cầu đọc một trạm kiểm soát và lặp lại 31 hoạt động.

Để cải thiện độ trơn của ứng dụng, trong một số trường hợp, có thể hữu ích khi tính toán lại khung điểm kiểm tra ở chế độ nền trong khi thao tác hoàn tác. Ví dụ, sau khi đã hoàn tác mười bảy hoạt động, một người có thể bắt đầu làm việc để tính toán các trạng thái cho 48, 40 và 36 bước trở lại từ điểm bắt đầu, để nếu một người muốn quay trở lại, người ta sẽ thực hiện một số công việc. Lưu ý rằng người ta có thể xóa các khung hình đã trở lại các hoạt động 1, 2, 4, 8 hoặc 16, vì người ta có thể tạo lại chúng bằng cách phát lại các lệnh chuyển tiếp từ trạng thái hiện tại.

+0

Phần khó khăn trong việc có khoảng thời gian không đổi (f0 = 1, f1 = 2, f2 = 4, f3 = 8, vv) giữa các khung hoàn tác là duy trì các khoảng thời gian này. Ví dụ, để đảm bảo f2 luôn luôn là bốn nét trước khi đột quỵ mới, bạn cần phải đi đến f3, và làm cho mọi đột quỵ ở giữa. Cùng một logic áp dụng cho f3, f4, vâng, bạn nên bắt đầu từ fmax (đó là canvas trống), nhưng điều đó thực sự có nghĩa là bạn cần phải xây dựng lại toàn bộ undo stack mỗi lần. – jlukanta

+0

@jlukanta: Không cần thiết phải có các trạm kiểm soát là khoảng cách chính xác trước khung hiện tại nếu chúng là khoảng cách từ một số khung hình trong tương lai. Nếu một số tất cả các khung hình từ lúc bắt đầu chỉnh sửa tại 1, thì một khung sẽ cố gắng có khung lẻ cuối cùng, số lẻ lẻ cuối cùng của 2, số lẻ lẻ cuối cùng của số bốn, v.v. Hơi khó mô tả sơ đồ tổng thể, nhưng về cơ bản kết thúc bằng cách sử dụng thời gian lgN – supercat