2017-01-22 20 views
7

Tôi đang làm việc trên một chương trình lấy một chuỗi, biến từng ký tự của chuỗi thành màu, sau đó vẽ các màu từ trái qua phải, từ trên xuống trên một hình ảnh. Hình ảnh sau đó có thể được giải mã bằng cách sử dụng cùng một chương trình để lấy lại tin nhắn gốc. Như một ví dụ, đây là clojure.core, mã hóa như một hình ảnh:Mã hóa một chuỗi dưới dạng ảnh gây nén

Clojure.core encoded as an image

tôi đã viết này cũng giống như một món đồ chơi, nhưng tôi nhận thấy một đặc tính thú vị của những hình ảnh nó tạo ra: chúng nhỏ hơn so với thông điệp ban đầu là dưới dạng văn bản. Đối với clojure.core, nó là 259kb dưới dạng văn bản, nhưng chỉ 88,9kb dưới dạng hình ảnh (ở trên) (cả hai giá trị là "kích thước trên đĩa"). Để đảm bảo dữ liệu không bị mất, tôi đã giải mã hình ảnh và nhận lại tin nhắn gốc.

Làm cách nào có thể? Tôi nghĩ rằng hình ảnh (định dạng png) sẽ có tiêu đề và thông tin bổ sung khác có thể làm tăng kích thước.

Toàn bộ clojure.core chứa 265486 ký tự (theo Notepad ++), có nghĩa là mỗi ký tự về cơ bản chiếm một byte.

Từ khi làm việc với lớp học BufferedImage (Java), nó xuất hiện như thể các màu được lưu trữ dưới dạng số nguyên 4 byte, vì vậy không phải mỗi pixel yêu cầu ~ 4x bộ nhớ?

Sau đây là cách nó được mã hóa:

  1. Ký tự đầu tiên của chuỗi được popped tắt

  2. Nó dịch sang một màu bằng cách đó là giá trị ASCII, nhân nó bằng một số lượng lớn (vì vậy nó bao gồm phạm vi màu sắc có thể tốt hơn), sau đó số đó được chuyển đổi thành một số 3, số cơ sở 256 ([123 100 200]).

  3. Mỗi chữ số được coi là kênh màu đỏ, xanh lục và xanh lam, được cung cấp cho phương thức setRGB của BufferedImage.

  4. Chỉ báo position nâng cao, ký tự tiếp theo sẽ xuất hiện và quá trình lặp lại cho đến khi toàn bộ thư được mã hóa.

Thuật toán này hơi phức tạp ngay bây giờ. @Thumbnail đề xuất một cách tốt hơn rất nhiều trên Code Review, nhưng tôi chưa thực hiện nó. Kể từ khi kết quả là như nhau mặc dù, điều đó không nên tạo sự khác biệt cho câu hỏi.

+2

Mặc dù câu trả lời có phần rõ ràng, tôi vẫn thích đọc về những phát hiện của bạn. Nó luôn luôn là niềm vui đến trên các công cụ như thế. –

Trả lời

7

Đồ họa mạng di động (PNG) là định dạng tệp đồ họa raster hỗ trợ nén dữ liệu không bị mất (từ https://en.wikipedia.org/wiki/Portable_Network_Graphics), iow. dữ liệu hình ảnh được nén khi được lưu dưới dạng tệp .png.

+0

Doh. Vâng đó là rõ ràng trong nhìn lại. Cảm ơn. – Carcigenicate

+0

Có thể đáng nhắc đến rằng PNG sử dụng nén Zlib/Deflate (và bạn có thể sẽ nhận được kết quả tốt hơn bằng cách sử dụng Deflate trực tiếp trên tệp văn bản). – haraldK

+0

@haraldK đó cũng là kỳ vọng của tôi. Ngoài việc giảm phát, png thực hiện việc chuyển tiền giúp nén ảnh "thực" (trong đó pixel, thống kê, trông rất giống với các pixel lân cận). Bạn có thể có thể tận dụng lợi thế này bằng cách chọn màu sắc gần nhau (do đó nhận được nén png tốt hơn).Không liên quan, nó có thể khả thi để làm cho hình ảnh kích thước nhỏ hơn bằng cách mã hóa nhiều hơn một ký tự trên mỗi pixel (hình ảnh truecolor + alpha png sử dụng 64 bit trên mỗi pixel) - điều này rất có thể sẽ không nén. – thebjorn

Các vấn đề liên quan