Thử thách mã hóa hình ảnh Twitter [đã đóng]


597

Nếu một bức tranh trị giá 1000 từ, bạn có thể ghép được bao nhiêu hình ảnh trong 140 ký tự?

Lưu ý : Đó là folks! Hạn chót của Bounty là ở đây, và sau khi cân nhắc kỹ lưỡng, tôi đã quyết định rằng mục nhập của Boojum chỉ vừa đủ để vượt qua Sam Hocevar . Tôi sẽ đăng ghi chú chi tiết hơn một khi tôi có cơ hội viết chúng lên. Tất nhiên, mọi người nên thoải mái tiếp tục gửi giải pháp và cải thiện giải pháp để mọi người bỏ phiếu. Cảm ơn tất cả những người đã gửi và nhập cảnh; Tôi rất thích tất cả chúng. Điều này đã mang lại rất nhiều niềm vui cho tôi khi chạy và tôi hy vọng nó sẽ thú vị cho cả những người tham gia và khán giả.

Tôi đã xem qua bài đăng thú vị này về việc cố gắng nén hình ảnh vào một bình luận trên Twitter và rất nhiều người trong chủ đề đó (và một chủ đề trên Reddit ) đã có đề xuất về các cách khác nhau mà bạn có thể làm. Vì vậy, tôi cho rằng nó sẽ tạo ra một thách thức mã hóa tốt; hãy để mọi người đặt tiền của họ ở nơi miệng của họ và cho thấy ý tưởng của họ về mã hóa có thể dẫn đến chi tiết hơn trong không gian hạn chế mà bạn có sẵn như thế nào.

Tôi thách bạn đưa ra một hệ thống mục đích chung để mã hóa hình ảnh thành tin nhắn Twitter 140 ký tự và giải mã chúng thành hình ảnh một lần nữa. Bạn có thể sử dụng các ký tự Unicode, do đó bạn nhận được nhiều hơn 8 bit cho mỗi ký tự. Tuy nhiên, ngay cả khi cho phép các ký tự Unicode, bạn sẽ cần phải nén hình ảnh vào một khoảng trống rất nhỏ; đây chắc chắn sẽ là một sự nén mất mát, và do đó sẽ phải có những đánh giá chủ quan về việc mỗi kết quả trông như thế nào.

Đây là kết quả mà tác giả ban đầu, Quasimondo , đã nhận được từ mã hóa của mình (hình ảnh được cấp phép theo giấy phép Creative Commons Attribution-NoncommIAL ): nàng mô na Li Sa

Bạn có thể làm tốt hơn không?

Quy tắc

  1. Chương trình của bạn phải có hai chế độ: mã hóagiải mã .
  2. Khi mã hóa :
    1. Chương trình của bạn phải lấy làm đầu vào một đồ họa ở bất kỳ định dạng đồ họa raster hợp lý nào bạn chọn. Chúng tôi sẽ nói rằng bất kỳ định dạng raster nào được ImageMagick hỗ trợ đều có giá trị hợp lý.
    2. Chương trình của bạn phải xuất ra một thông báo có thể được biểu thị bằng 140 hoặc ít hơn các điểm mã Unicode; 140 điểm mã trong phạm vi U+0000- U+10FFFF, trừ phi nhân vật ( U+FFFE, U+FFFF, U+nFFFE , U+nFFFF nơi n1- 10thập lục phân, và phạm vi U+FDD0- U+FDEF) và điểm mã thay thế ( U+D800- U+DFFF). Nó có thể là đầu ra trong bất kỳ mã hóa hợp lý nào của sự lựa chọn của bạn; mọi mã hóa được GNUiconv hỗ trợ sẽ được coi là hợp lý và mã hóa gốc hoặc mã hóa ngôn ngữ nền tảng của bạn có thể là một lựa chọn tốt. Xem ghi chú Unicode bên dưới để biết thêm chi tiết.
  3. Khi giải mã :
    1. Chương trình của bạn sẽ lấy đầu vào là đầu ra của chế độ mã hóa .
    2. Chương trình của bạn phải xuất hình ảnh ở bất kỳ định dạng hợp lý nào bạn chọn, như được xác định ở trên, mặc dù đối với các định dạng vectơ đầu ra cũng ổn.
    3. Đầu ra hình ảnh phải là một xấp xỉ của hình ảnh đầu vào; bạn càng có thể đến gần hình ảnh đầu vào thì càng tốt.
    4. Quá trình giải mã có thể không có quyền truy cập vào bất kỳ đầu ra nào khác của quá trình mã hóa ngoài đầu ra được chỉ định ở trên; nghĩa là, bạn không thể tải lên hình ảnh ở đâu đó và xuất URL cho quá trình giải mã để tải xuống hoặc bất cứ điều gì ngớ ngẩn như thế.
  4. Để đảm bảo tính nhất quán trong giao diện người dùng, chương trình của bạn phải hoạt động như sau:

    1. Chương trình của bạn phải là một tập lệnh có thể được đặt thành có thể thực thi được trên một nền tảng với trình thông dịch phù hợp hoặc chương trình có thể được biên dịch thành tệp thực thi.
    2. Chương trình của bạn phải lấy làm đối số đầu tiên encodehoặc decodeđể đặt chế độ.
    3. Chương trình của bạn phải nhận đầu vào theo một hoặc nhiều cách sau (nếu bạn triển khai tên lấy tên tệp, bạn cũng có thể đọc và ghi từ stdin và stdout nếu tên tệp bị thiếu):

      1. Lấy đầu vào từ tiêu chuẩn trong và sản xuất đầu ra trên tiêu chuẩn ra.

        my-program encode <input.png >output.txt
        my-program decode <output.txt >output.png
        
      2. Lấy đầu vào từ một tệp có tên trong đối số thứ hai và tạo đầu ra trong tệp có tên trong đối số thứ ba.

        my-program encode input.png output.txt
        my-program decode output.txt output.png
        
  5. Đối với giải pháp của bạn, xin vui lòng gửi:
    1. Mã của bạn, đầy đủ và / hoặc một liên kết đến nó được lưu trữ ở nơi khác (nếu nó rất dài hoặc yêu cầu nhiều tệp để biên dịch, hoặc một cái gì đó).
    2. Một lời giải thích về cách thức hoạt động của nó, nếu nó không rõ ràng ngay lập tức từ mã hoặc nếu mã dài và mọi người sẽ quan tâm đến một bản tóm tắt.
    3. Một hình ảnh ví dụ, với hình ảnh gốc, văn bản mà nó nén xuống và hình ảnh được giải mã.
    4. Nếu bạn đang xây dựng một ý tưởng mà người khác có, xin hãy ghi nhận chúng. Bạn có thể cố gắng hoàn thiện ý tưởng của người khác, nhưng bạn phải quy kết chúng.

Hướng dẫn

Về cơ bản, đây là các quy tắc có thể bị phá vỡ, đề xuất hoặc tiêu chí chấm điểm:

  1. Thẩm mỹ là quan trọng. Tôi sẽ phán xét và đề nghị người khác phán xét, dựa trên:
    1. Hình ảnh đầu ra trông tốt như thế nào, và nó trông giống như bản gốc bao nhiêu.
    2. Văn bản trông đẹp như thế nào. Gobbledigook hoàn toàn ngẫu nhiên là ổn nếu bạn có một sơ đồ nén thực sự thông minh, nhưng tôi cũng muốn xem câu trả lời biến hình ảnh thành những bài thơ đa ngôn ngữ, hoặc một cái gì đó thông minh như thế. Lưu ý rằng tác giả của giải pháp ban đầu đã quyết định chỉ sử dụng các ký tự Trung Quốc, vì nó trông đẹp hơn theo cách đó.
    3. Mã thú vị và thuật toán thông minh luôn luôn tốt. Tôi thích ngắn, đến mức, và mã rõ ràng, nhưng các thuật toán phức tạp thực sự thông minh là OK miễn là chúng tạo ra kết quả tốt.
  2. Tốc độ cũng rất quan trọng, mặc dù không quan trọng bằng việc công việc nén hình ảnh bạn làm tốt đến mức nào. Tôi muốn có một chương trình có thể chuyển đổi một hình ảnh trong một phần mười giây so với một chương trình sẽ chạy các thuật toán di truyền trong nhiều ngày.
  3. Tôi sẽ thích các giải pháp ngắn hơn cho các giải pháp dài hơn, miễn là chúng tương đối hợp lý về chất lượng; sự đồng tình là một đức tính
  4. Chương trình của bạn nên được triển khai bằng ngôn ngữ có triển khai miễn phí trên Mac OS X, Linux hoặc Windows. Tôi muốn có thể chạy các chương trình, nhưng nếu bạn có một giải pháp tuyệt vời chỉ chạy theo MATLAB hoặc một cái gì đó, thì tốt thôi.
  5. Chương trình của bạn nên càng chung chung càng tốt; nó nên hoạt động với càng nhiều hình ảnh khác nhau càng tốt, mặc dù một số có thể tạo ra kết quả tốt hơn những hình ảnh khác. Đặc biệt:
    1. Có một vài hình ảnh được tích hợp vào chương trình phù hợp và viết tham chiếu đến, sau đó tạo ra hình ảnh phù hợp khi giải mã, khá khập khiễng và sẽ chỉ bao gồm một vài hình ảnh.
    2. Một chương trình có thể lấy hình ảnh của các hình dạng đơn giản, phẳng, hình học và phân tách chúng thành một số nguyên thủy véc tơ là khá tiện lợi, nhưng nếu nó thất bại trên các hình ảnh vượt quá độ phức tạp nhất định thì có lẽ không đủ chung chung.
    3. Một chương trình chỉ có thể chụp ảnh với tỷ lệ khung hình cố định cụ thể nhưng thực hiện tốt công việc với chúng cũng sẽ ổn, nhưng không lý tưởng.
    4. Bạn có thể thấy rằng một hình ảnh đen trắng có thể thu được nhiều thông tin vào một không gian nhỏ hơn một hình ảnh màu. Mặt khác, điều đó có thể giới hạn các loại hình ảnh mà nó áp dụng; khuôn mặt trở nên đẹp với màu đen và trắng, nhưng thiết kế trừu tượng có thể không phù hợp lắm.
    5. Hoàn toàn ổn nếu hình ảnh đầu ra nhỏ hơn đầu vào, trong khi có cùng tỷ lệ. Sẽ ổn nếu bạn phải phóng to hình ảnh lên để so sánh nó với bản gốc; Điều quan trọng là nó trông như thế nào.
  6. Chương trình của bạn sẽ tạo ra đầu ra thực sự có thể đi qua Twitter và đi ra ngoài vô tư. Đây chỉ là một hướng dẫn chứ không phải là một quy tắc, vì tôi không thể tìm thấy bất kỳ tài liệu nào về bộ ký tự chính xác được hỗ trợ, nhưng có lẽ bạn nên tránh các ký tự điều khiển, các ký tự kết hợp vô hình thú vị, các ký tự sử dụng riêng tư và tương tự.

Chấm điểm

Là một hướng dẫn chung về cách tôi sẽ xếp hạng các giải pháp khi chọn giải pháp được chấp nhận của mình, giả sử rằng tôi có thể sẽ đánh giá các giải pháp theo thang điểm 25 (điều này rất khó hiểu và tôi sẽ không được chấm điểm trực tiếp, chỉ cần sử dụng đây là một hướng dẫn cơ bản):

  • 15 điểm cho sơ đồ mã hóa tái tạo một loạt các hình ảnh đầu vào tốt như thế nào. Đây là một đánh giá chủ quan, thẩm mỹ
    • 0 có nghĩa là nó hoàn toàn không hoạt động, nó trả lại hình ảnh giống nhau mỗi lần hoặc một cái gì đó
    • 5 có nghĩa là nó có thể mã hóa một vài hình ảnh, mặc dù phiên bản được giải mã trông xấu và nó có thể không hoạt động trên các hình ảnh phức tạp hơn
    • 10 có nghĩa là nó hoạt động trên một loạt các hình ảnh và tạo ra những hình ảnh dễ chịu mà đôi khi có thể phân biệt được
    • 15 có nghĩa là nó tạo ra các bản sao hoàn hảo của một số hình ảnh, và thậm chí đối với các hình ảnh lớn hơn và phức tạp hơn, mang lại một cái gì đó dễ nhận biết. Hoặc, có lẽ nó không tạo ra những hình ảnh khá dễ nhận biết, nhưng tạo ra những hình ảnh đẹp có nguồn gốc rõ ràng từ bản gốc.
  • 3 điểm để sử dụng thông minh bộ ký tự Unicode
    • 0 điểm chỉ đơn giản là sử dụng toàn bộ bộ ký tự được phép
    • 1 điểm cho việc sử dụng một bộ ký tự giới hạn an toàn để chuyển qua Twitter hoặc trong nhiều tình huống khác nhau
    • 2 điểm cho việc sử dụng tập hợp con các ký tự theo chủ đề, chẳng hạn như chỉ các chữ tượng hình chữ Hán hoặc chỉ các ký tự từ phải sang trái
    • 3 điểm để làm một cái gì đó thực sự gọn gàng, như tạo văn bản có thể đọc hoặc sử dụng các ký tự trông giống như hình ảnh trong câu hỏi
  • 3 điểm cho cách tiếp cận thuật toán thông minh và kiểu mã
    • 0 điểm cho thứ gì đó là 1000 dòng mã chỉ để thu nhỏ hình ảnh xuống, coi nó là 1 bit trên mỗi pixel và mã hóa base64
    • 1 điểm cho một cái gì đó sử dụng một kỹ thuật mã hóa tiêu chuẩn và được viết tốt và ngắn gọn
    • 2 điểm cho một cái gì đó giới thiệu một kỹ thuật mã hóa tương đối mới, hoặc đó là ngắn và đáng ngạc nhiên
    • 3 điểm cho một lớp lót thực sự tạo ra kết quả tốt hoặc thứ gì đó phá vỡ nền tảng mới trong mã hóa đồ họa (nếu điều này có vẻ như là một số điểm thấp để phá vỡ nền tảng mới, hãy nhớ rằng kết quả tốt này sẽ có điểm cao về tính thẩm mỹ cũng)
  • 2 điểm cho tốc độ. Tất cả những thứ khác đều bằng nhau, nhanh hơn là tốt hơn, nhưng các tiêu chí trên đều quan trọng hơn tốc độ
  • 1 điểm để chạy trên phần mềm miễn phí (nguồn mở), vì tôi thích phần mềm miễn phí (lưu ý rằng C # vẫn sẽ đủ điều kiện cho điểm này miễn là nó chạy trên Mono, tương tự mã MATLAB sẽ đủ điều kiện nếu chạy trên GNU Octave)
  • 1 điểm cho việc thực sự tuân theo tất cả các quy tắc. Các quy tắc này đã trở nên hơi lớn và phức tạp, vì vậy tôi có thể chấp nhận các câu trả lời tốt có sai một chi tiết nhỏ, nhưng tôi sẽ đưa ra một điểm bổ sung cho bất kỳ giải pháp nào thực sự tuân theo tất cả các quy tắc

Hình ảnh tham khảo

Một số người đã yêu cầu một số hình ảnh tham khảo. Dưới đây là một vài hình ảnh tham khảo mà bạn có thể thử; các phiên bản nhỏ hơn được nhúng ở đây, tất cả đều liên kết đến các phiên bản lớn hơn của hình ảnh nếu bạn cần:

Lena nàng mô na Li Sa Hộp ngô Logo StackOverflow

Giải thưởng

Tôi đang cung cấp một khoản tiền thưởng 500 rep (cộng với 50 mà StackOverflow khởi động) cho giải pháp mà tôi thích nhất, dựa trên các tiêu chí trên. Tất nhiên, tôi khuyến khích mọi người khác bỏ phiếu cho các giải pháp yêu thích của họ ở đây là tốt.

Lưu ý về thời hạn

Cuộc thi này sẽ diễn ra cho đến khi hết tiền thưởng, khoảng 6 giờ tối ngày thứ bảy, 30 tháng 5. Tôi không thể nói thời gian chính xác sẽ kết thúc; nó có thể là bất cứ nơi nào từ 5 đến 7 giờ tối. Tôi sẽ đảm bảo rằng tôi sẽ xem xét tất cả các mục được gửi trước 2 giờ chiều và tôi sẽ cố gắng hết sức để xem tất cả các mục được gửi trước 4 giờ chiều; nếu các giải pháp được gửi sau đó, tôi có thể không có cơ hội để cung cấp cho họ một cái nhìn công bằng trước khi tôi phải đưa ra quyết định của mình. Ngoài ra, bạn gửi càng sớm, bạn càng có nhiều cơ hội bỏ phiếu để có thể giúp tôi chọn giải pháp tốt nhất, vì vậy hãy thử và gửi sớm hơn thay vì đúng thời hạn.

Ghi chú Unicode

Cũng có một số nhầm lẫn về chính xác những gì các ký tự Unicode được cho phép. Phạm vi của các điểm mã Unicode có thể là U+0000để U+10FFFF. Có một số điểm mã không bao giờ hợp lệ để sử dụng làm ký tự Unicode trong bất kỳ trao đổi dữ liệu mở nào; đây là các ký tự không thay thế và các điểm mã thay thế . Noncharacters được định nghĩa trong Unidode Chuẩn 5.1.0 phần 16,7 như các giá trị U+FFFE, U+FFFF, U+nFFFE , U+nFFFF nơi n1- 10thập lục phân, và phạm vi U+FDD0-U+FDEF. Các giá trị này được dự định sẽ được sử dụng cho mục đích sử dụng nội bộ dành riêng cho ứng dụng và các ứng dụng tuân thủ có thể loại bỏ các ký tự này khỏi văn bản được xử lý bởi chúng. Các điểm mã thay thế, được xác định trong phần Tiêu chuẩn Unicode 5.1.0 như U+D800- U+DFFF, được sử dụng để mã hóa các ký tự ngoài Mặt phẳng đa ngôn ngữ cơ bản trong UTF-16; do đó, không thể biểu diễn trực tiếp các điểm mã này trong mã hóa UTF-16 và không hợp lệ để mã hóa chúng trong bất kỳ mã hóa nào khác. Do đó, với mục đích của cuộc thi này, tôi sẽ cho phép bất kỳ chương trình nào mã hóa hình ảnh thành một chuỗi không quá 140 điểm mã Unicode trong phạm vi U+0000- U+10FFFF, ngoại trừ tất cả các cặp không ký tự và thay thế như được định nghĩa ở trên.

Tôi sẽ thích các giải pháp chỉ sử dụng các ký tự được gán và thậm chí các giải pháp tốt hơn sử dụng các tập hợp con thông minh của các ký tự được gán hoặc làm điều gì đó thú vị với bộ ký tự mà chúng sử dụng. Để biết danh sách các ký tự được gán, hãy xem Cơ sở dữ liệu Ký tự Unicode ; lưu ý rằng một số ký tự được liệt kê trực tiếp, trong khi một số ký tự chỉ được liệt kê dưới dạng bắt đầu và kết thúc của một phạm vi. Cũng lưu ý rằng các điểm mã thay thế được liệt kê trong cơ sở dữ liệu, nhưng bị cấm như đã đề cập ở trên. Nếu bạn muốn tận dụng các thuộc tính nhất định của các ký tự để làm cho văn bản bạn xuất ra thú vị hơn, có nhiều cơ sở dữ liệu thông tin ký tự có sẵn, chẳng hạn như danh sách các khối mã được đặt têncác thuộc tính ký tự khác nhau.

Vì Twitter không chỉ định chính xác bộ ký tự mà họ hỗ trợ, tôi sẽ khoan dung về các giải pháp không thực sự hoạt động với Twitter vì một số ký tự nhất định đếm thêm hoặc một số ký tự nhất định bị tước. Nó được ưa chuộng nhưng không bắt buộc rằng tất cả các kết quả đầu ra được mã hóa sẽ có thể được chuyển giao không hề hấn gì qua Twitter hoặc dịch vụ tiểu blog khác như identi.ca . Tôi đã thấy một số tài liệu nói rằng mã hóa thực thể Twitter <,> và &, và do đó tính các ký tự tương ứng là 4, 4 và 5 ký tự, nhưng tôi đã không tự mình kiểm tra và bộ đếm ký tự JavaScript của chúng dường như không để đếm chúng theo cách đó.

Mẹo & Liên kết

  • Định nghĩa của các ký tự Unicode hợp lệ trong các quy tắc là một chút phức tạp. Chọn một khối ký tự duy nhất, chẳng hạn như Ideograph Thống nhất của CJK (U + 4E00, U + 9FCF) có thể dễ dàng hơn.
  • Bạn có thể sử dụng các thư viện hình ảnh hiện có, như Thư viện hình ảnh ImageMagick hoặc Python , để thao tác hình ảnh của bạn.
  • Nếu bạn cần một số trợ giúp để hiểu bộ ký tự Unicode và các bảng mã khác nhau, hãy xem hướng dẫn nhanh này hoặc Câu hỏi thường gặp chi tiết này về UTF-8 trong Linux và Unix .
  • Bạn càng sớm nhận được giải pháp của mình, tôi (và những người khác sẽ bỏ phiếu càng nhiều thời gian). Bạn có thể chỉnh sửa giải pháp của mình nếu bạn cải thiện nó; Tôi sẽ dựa vào tiền thưởng của mình trên phiên bản mới nhất khi tôi xem qua các giải pháp.
  • Nếu bạn muốn một định dạng hình ảnh dễ dàng phân tích và viết (và không muốn chỉ sử dụng một định dạng hiện có), tôi khuyên bạn nên sử dụng định dạng PPM . Đây là định dạng dựa trên văn bản rất dễ làm việc và bạn có thể sử dụng ImageMagick để chuyển đổi sang và từ đó.

Vui lòng đưa ra đề xuất về các quy tắc tôi đã viết trong các ý kiến; Tôi chắc chắn sẵn sàng tinh chỉnh chúng nếu mọi người cảm thấy cần làm rõ hoặc quá cụ thể.
Brian Campbell

6
Bạn có thể nên nói rằng tải hình ảnh lên máy chủ và đăng url lên nó là không hợp lệ.
Shay Erlichmen

2
@Shay Tôi đã không nói điều đó? "Quá trình giải mã có thể không có quyền truy cập vào bất kỳ đầu ra nào khác của quá trình mã hóa ngoài đầu ra được chỉ định ở trên; nghĩa là bạn không thể tải lên hình ảnh ở đâu đó và xuất URL cho quá trình giải mã để tải xuống hoặc bất cứ điều gì ngớ ngẩn như thế . "
Brian Campbell

1
@Konrad Rudolph Tôi đồng ý; Tôi không có nghĩa là "ngớ ngẩn" từ quan điểm thực tế (rõ ràng, toàn bộ cuộc thi này là ngớ ngẩn từ quan điểm thực tế), tôi có nghĩa là "ngớ ngẩn" trong bối cảnh của cuộc thi này. Sử dụng URI không thực sự là một thuật toán nén, theo nghĩa lý thuyết thông tin, vì nó không cho phép bạn chuyển thêm bất kỳ thông tin nào mà không cần sử dụng một kênh thay thế. Bạn có thể cung cấp cho bộ mã hóa và bộ giải mã một cơ sở dữ liệu hình ảnh lớn và gọi nó là nén chỉ hoạt động trên một tập hợp hình ảnh giới hạn, nhưng tôi đã chỉ định rằng bạn cần có khả năng xử lý một hình ảnh tùy ý.
Brian Campbell

2
Dưới đây là một số liên kết tôi đã chạy qua có thể giúp mọi người hiểu rõ: azillionmonkeys.com/qed/unicode.html để giải thích về phạm vi ký tự Unicode hợp lệ. Lưu ý rằng các mã hóa UTF là các mã hóa có thể mã hóa toàn bộ phạm vi Unicode; UCS-4 là một siêu bộ của Unicode và UCS-2 & ASCII là các tập con. Và trên mặt nén, đây là một kỹ thuật tương tự như bài gốc, mặc dù anh ấy cho phép mình 1k chứ không phải 350 byte: shoutingduck.com/Article.php?ArticleID=46&Show=ABCE
Brian Campbell

Câu trả lời:


244

Được rồi, đây là của tôi: nanocunch.cpp và tệp CMakeLists.txt để xây dựng nó bằng CMake. Nó phụ thuộc vào API ImageMagick của Magick cho hầu hết việc xử lý hình ảnh của nó. Nó cũng yêu cầu thư viện GMP cho số học bignum để mã hóa chuỗi.

Tôi dựa trên giải pháp của mình về nén hình ảnh fractal, với một vài vòng xoắn độc đáo. Ý tưởng cơ bản là lấy hình ảnh, giảm tỷ lệ bản sao xuống 50% và tìm kiếm các mảnh theo các hướng khác nhau trông giống như các khối không chồng lấp trong ảnh gốc. Nó cần một cách tiếp cận rất mạnh mẽ cho tìm kiếm này, nhưng điều đó chỉ làm cho việc giới thiệu các sửa đổi của tôi dễ dàng hơn.

Điều chỉnh đầu tiên là thay vì chỉ nhìn vào chín mươi độ và lật, chương trình của tôi cũng xem xét các định hướng 45 độ. Đó là thêm một bit cho mỗi khối, nhưng nó giúp chất lượng hình ảnh vô cùng lớn.

Một điều khác là việc lưu trữ một điều chỉnh độ tương phản / độ sáng cho từng thành phần màu của mỗi khối là quá đắt. Thay vào đó, tôi lưu trữ một màu được lượng tử hóa nhiều (bảng màu chỉ có 4 * 4 * 4 = 64 màu) chỉ đơn giản là được pha trộn theo một tỷ lệ nào đó. Về mặt toán học, điều này tương đương với độ sáng thay đổi và điều chỉnh độ tương phản không đổi cho mỗi màu. Thật không may, điều đó cũng có nghĩa là không có sự tương phản tiêu cực để lật các màu.

Sau khi tính toán vị trí, hướng và màu sắc cho mỗi khối, nó mã hóa chuỗi này thành chuỗi UTF-8. Đầu tiên, nó tạo ra một khối lượng rất lớn để thể hiện dữ liệu trong bảng khối và kích thước hình ảnh. Cách tiếp cận này tương tự như giải pháp của Sam Hocevar - một số lượng lớn với cơ số thay đổi theo vị trí.

Sau đó, nó chuyển đổi nó thành một cơ sở của bất kỳ kích thước nào của bộ ký tự có sẵn. Theo mặc định, nó sử dụng đầy đủ bộ ký tự unicode được gán, trừ đi ít hơn, lớn hơn, ký hiệu, điều khiển, kết hợp và ký tự thay thế và ký tự riêng. Nó không đẹp nhưng nó hoạt động. Bạn cũng có thể nhận xét bảng mặc định và chọn ASCII 7 bit có thể in được (một lần nữa loại trừ <,> và & ký tự) hoặc Ideograph Thống nhất của CJK thay thế. Bảng có mã ký tự có sẵn được lưu trữ được mã hóa độ dài chạy với các ký tự không hợp lệ và hợp lệ xen kẽ.

Dù sao, đây là một số hình ảnh và thời gian (như được đo trên P4 3.0GHz cũ của tôi) và được nén thành 140 ký tự trong bộ unicode được gán đầy đủ được mô tả ở trên. Nhìn chung, tôi khá hài lòng với cách tất cả chúng bật ra. Nếu tôi có nhiều thời gian hơn để làm việc này, có lẽ tôi sẽ cố gắng giảm độ chặn của các hình ảnh được giải nén. Tuy nhiên, tôi nghĩ rằng kết quả là khá tốt cho tỷ lệ nén cực cao. Các hình ảnh giải nén là bit ấn tượng, nhưng tôi thấy tương đối dễ dàng để xem các bit tương ứng với bản gốc như thế nào.

Logo Overflow (8.6s để mã hóa, 7.9 giây để giải mã, 485 byte):
http://i44.tinypic.com/2w7lok1.png

Lena (32,8 giây để mã hóa, 13,0 giây để giải mã, 477 byte):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png

Mona Lisa (43,2 giây để mã hóa, 14,5 giây để giải mã, 490 byte):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png

Chỉnh sửa: Nhân vật hợp nhất của CJK

Sam hỏi trong các ý kiến ​​về việc sử dụng điều này với CJK. Đây là phiên bản của Mona Lisa được nén thành 139 ký tự từ bộ ký tự Hợp nhất của CJK:

http://i43.tinypic.com/2yxgdfk.png 咏 璘 驞隤 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛 慛伆 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇 杇擸 萿

Các tham số điều chỉnh ở đầu chương trình mà tôi đã sử dụng cho điều này là: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. Tôi cũng đã nhận xét định nghĩa đầu tiên về number_assign và mã, và không bị bỏ sót định nghĩa cuối cùng của chúng để chọn bộ ký tự hợp nhất CJK.


Ồ Công việc tốt. Tôi đã hoài nghi về nén hình ảnh fractal cho hình ảnh nhỏ này, nhưng nó thực sự tạo ra kết quả khá tốt. Nó cũng khá dễ dàng để biên dịch và chạy.
Brian Campbell

1
Cảm ơn các bạn! Sam, ý bạn là kết quả chỉ với 140 ký tự CJK? Nếu vậy, thì có, bạn sẽ cần điều chỉnh các số ở trên cùng. Kích thước cuối cùng trong bit là khoảng log2 (steps_in_x steps_in_y steps_in_red steps_in_green steps_in_blue) * blocks_in_x blocks_in_y + log2 (maximum_width maximum_height).
Boojum

Chỉnh sửa: Có * 16 trong log2 () đầu tiên mà tôi bỏ qua. Đó là cho những định hướng có thể.
Boojum

20
Có ai đã twitter một hình ảnh bằng cách này chưa?
dbr

288

tập tin hình ảnh và nguồn python (phiên bản 1 và 2)

Phiên bản 1 Đây là nỗ lực đầu tiên của tôi. Tôi sẽ cập nhật khi tôi đi.

Tôi đã có logo SO xuống tới 300 ký tự gần như không mất. Kỹ thuật của tôi sử dụng chuyển đổi sang nghệ thuật vector SVG để nó hoạt động tốt nhất trên nghệ thuật đường. Nó thực sự là một máy nén SVG, nó vẫn đòi hỏi nghệ thuật ban đầu phải trải qua giai đoạn vector hóa.

Trong lần thử đầu tiên, tôi đã sử dụng một dịch vụ trực tuyến cho dấu vết PNG tuy nhiên có NHIỀU công cụ miễn phí và không miễn phí có thể xử lý phần này bao gồm cả potrace (nguồn mở).

Đây là kết quả

Logo SO gốc http: //www.war Warriorhut.org/graphics/svg_to_unicode/so-logo.png Logo SO được giải mã gốc http: //www.war Warriorhut.org/graphics/svg_to_unicode/so-logo-decoding.png Sau khi mã hóa và giải mã

Nhân vật : 300

Thời gian : Không được đo nhưng thực tế là ngay lập tức (không bao gồm các bước vector hóa / rasterisation)

Giai đoạn tiếp theo sẽ là nhúng 4 ký hiệu (các điểm và lệnh đường dẫn SVG) cho mỗi ký tự unicode. Hiện tại, bản dựng python của tôi không có ký tự rộng hỗ trợ UCS4, điều này giới hạn độ phân giải của tôi trên mỗi ký tự. Tôi cũng đã giới hạn phạm vi tối đa ở đầu dưới của phạm vi dành riêng unicode 0xD800, tuy nhiên một khi tôi xây dựng danh sách các ký tự được phép và bộ lọc để tránh chúng, về mặt lý thuyết tôi có thể đẩy số lượng ký tự được yêu cầu thấp tới 70-100 cho logo ở trên.

Một hạn chế của phương pháp này hiện nay là kích thước đầu ra không cố định. Nó phụ thuộc vào số lượng nút / điểm vector sau khi vector hóa. Tự động hóa giới hạn này sẽ yêu cầu pixel hóa hình ảnh (loại bỏ lợi ích chính của vectơ) hoặc lặp đi lặp lại các đường dẫn qua giai đoạn đơn giản hóa cho đến khi đạt được số nút mong muốn (hiện tôi đang thực hiện thủ công trong Inkscape).

Phiên bản 2

CẬP NHẬT : v2 hiện đủ điều kiện để cạnh tranh. Thay đổi:

  • Đầu vào / đầu ra và gỡ lỗi điều khiển dòng lệnh
  • Sử dụng trình phân tích cú pháp XML (lxml) để xử lý SVG thay vì regex
  • Gói 2 đoạn đường dẫn cho mỗi ký hiệu unicode
  • Tài liệu và dọn dẹp
  • Hỗ trợ style = "fill: color" và fill = "color"
  • Chiều rộng / chiều cao của tài liệu được đóng gói thành một ký tự
  • Màu đường dẫn được đóng gói thành một ký tự
  • Nén màu được thực hiện bằng cách loại bỏ 4 bit dữ liệu màu cho mỗi màu sau đó đóng gói thành ký tự thông qua chuyển đổi hex.

Nhân vật : 133

Thời gian : Vài giây

v2 đã giải mã http: //www.war Warriorhut.org/graphics/svg_to_unicode/so-logo-decoding-v2.png Sau khi mã hóa và giải mã (phiên bản 2)

Như bạn có thể thấy có một số hiện vật lần này. Đó không phải là một hạn chế của phương pháp mà là một lỗi ở đâu đó trong các chuyển đổi của tôi. Các tạo tác xảy ra khi các điểm nằm ngoài phạm vi 0,0 - 127,0 và những nỗ lực của tôi để hạn chế chúng đã có thành công hỗn hợp. Giải pháp đơn giản là thu nhỏ hình ảnh xuống, tuy nhiên tôi gặp khó khăn khi thu nhỏ điểm thực tế hơn là ma trận nghệ thuật hoặc nhóm và bây giờ tôi quá mệt mỏi để quan tâm. Nói tóm lại, nếu điểm của bạn nằm trong phạm vi được hỗ trợ thì nó thường hoạt động.

Tôi tin rằng kink ở giữa là do một tay cầm di chuyển sang phía bên kia của tay cầm mà nó được liên kết. Về cơ bản các điểm quá gần nhau ngay từ đầu. Chạy bộ lọc đơn giản hóa qua hình ảnh nguồn trước khi nén nó sẽ khắc phục điều này và cạo một số ký tự không cần thiết.

CẬP NHẬT : Phương pháp này tốt cho các đối tượng đơn giản vì vậy tôi cần một cách để đơn giản hóa các đường dẫn phức tạp và giảm nhiễu. Tôi đã sử dụng Inkscape cho nhiệm vụ này. Tôi đã có một số may mắn với việc chải chuốt những con đường không cần thiết bằng Inkscape nhưng không có thời gian để thử tự động hóa nó. Tôi đã tạo một số svss mẫu bằng cách sử dụng chức năng 'Đơn giản hóa' của Inkscape để giảm số lượng đường dẫn.

Đơn giản hóa hoạt động ok nhưng nó có thể chậm với nhiều đường dẫn này.

ví dụ về autotrace http: //www.war Warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_redraction.png hộp cornell /svg_to_unicode/lena_std_washing_autotrace.png

hình thu nhỏ truy tìm http: //www.war Warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

Đây là một số bức ảnh độ phân giải cực thấp. Chúng sẽ gần với giới hạn 140 ký tự hơn mặc dù cũng có thể cần một số đường dẫn thông minh.

chải chuốt http: //www.war Warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png Đơn giản hóa và xem thường.

tam giác http: //www.war Warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulation.png Đơn giản hóa, xem thường và tam giác.

autotrace --output-format svg --output-file cornell_box.svg --despeckle-level 20 --color-count 64 cornell_box.png

TRÊN: Đơn giản hóa đường dẫn sử dụng autotrace .

Thật không may, trình phân tích cú pháp của tôi không xử lý đầu ra tự động ghi lại vì vậy tôi không biết các điểm có thể được sử dụng như thế nào hoặc đơn giản hóa đến mức nào, đáng buồn là có ít thời gian để viết nó trước thời hạn. Nó dễ phân tích hơn nhiều so với đầu ra inkscape.


2
Thông minh! Lúc đầu, tôi muốn tạo ra một giải pháp vectơ lai có cả các cạnh sắc nét và các vùng mịn, nhưng nó tỏ ra quá phức tạp khi không sử dụng thư viện theo dõi (mà tôi không muốn sử dụng). Tôi đang mong đợi để xem bạn có thể đi được bao xa với phương pháp của mình!
sam hocevar

Đẹp! Tôi đã hy vọng chúng ta sẽ thấy một số nỗ lực theo cách tiếp cận gần như không mất mát bằng cách vector hóa. Nó có nghĩa là nó có tính tổng quát thấp hơn, nhưng chất lượng cao hơn cho hình ảnh mà nó bao phủ. Thật tốt khi sử dụng một dịch vụ trực tuyến để vector hóa. Chúc may mắn về việc giảm kích thước hơn nữa!
Brian Campbell

Tôi sẽ coi nén hình ảnh và mã hóa ký tự là hai bước khác nhau - Kỹ thuật của Sam dường như là tối ưu cho mã hóa và có thể dễ dàng được xây dựng thành một chương trình độc lập. Bạn sẽ nhận được nhiều hơn cho đồng tiền của mình bằng cách tập trung vào phần duy nhất của giải pháp của bạn (tức là phần nén) và chỉ xuất ra một chuỗi bit.
Đánh dấu tiền chuộc

70
Ồ Những hình ảnh này trông thực sự phong cách.
Rinat Abdullin

199

Giải pháp đầy đủ của tôi có thể được tìm thấy tại http://caca.zoy.org/wiki/img2twit . Nó có các tính năng sau:

  • Thời gian nén hợp lý (khoảng 1 phút cho chất lượng cao)
  • Giải nén nhanh (một phần của giây)
  • Giữ kích thước hình ảnh gốc (không chỉ tỷ lệ khung hình)
  • Chất lượng tái thiết Decent (IMHO)
  • Độ dài thông báo và bộ ký tự (ASCII, CJK, Symbols) có thể được chọn trong thời gian chạy
  • Độ dài tin nhắn và bộ ký tự được tự động phát hiện tại thời điểm giải nén
  • Đóng gói thông tin rất hiệu quả

http://caca.zoy.org/raw-attachment/wiki/img2twit/so-logo.png http://caca.zoy.org/raw-attachment/wiki/img2twit/twitter4.png

蜥 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓 秓玧 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫 霫舥 攩

Dưới đây là tổng quan sơ bộ về quá trình mã hóa:

  • Số lượng bit khả dụng được tính từ độ dài tin nhắn mong muốn và bộ ký tự có thể sử dụng
  • Hình ảnh nguồn được phân đoạn thành nhiều ô vuông như các bit có sẵn cho phép
  • Một số điểm cố định (hiện là 2) bị ảnh hưởng đến từng ô, với tọa độ ban đầu và giá trị màu
  • Sau đây được lặp lại cho đến khi một điều kiện chất lượng được đáp ứng:
    • Một điểm được chọn ngẫu nhiên
    • Một thao tác được thực hiện ngẫu nhiên vào thời điểm này (di chuyển nó vào trong ô của nó, thay đổi màu sắc của nó)
    • Nếu hình ảnh thu được (xem quy trình giải mã bên dưới) gần với hình ảnh nguồn hơn, thao tác được giữ
  • Kích thước hình ảnh và danh sách các điểm được mã hóa trong UTF-8

Và đây là quá trình giải mã:

  • Kích thước hình ảnh và điểm được đọc từ luồng UTF-8
  • Đối với mỗi pixel trong ảnh đích:
    • Danh sách các neigbours tự nhiên được tính toán
    • Màu cuối cùng của pixel được đặt ở mức trung bình có trọng số của các màu lân cận tự nhiên của pixel

Những gì tôi tin là phần nguyên bản nhất của chương trình là dòng bit. Thay vì đóng gói các giá trị được căn chỉnh bit ( stream <<= shift; stream |= value), tôi đóng gói các giá trị tùy ý không nằm trong phạm vi sức mạnh của hai phạm vi ( stream *= range; stream += value). Điều này đòi hỏi tính toán bignum và tất nhiên là chậm hơn rất nhiều, nhưng nó mang lại cho tôi 2009,18 bit thay vì năm 1960 khi sử dụng 20902 ký tự chính của CJK (đó là ba điểm nữa tôi có thể đưa vào dữ liệu). Và khi sử dụng ASCII, nó mang lại cho tôi 917,64 bit thay vì 840.

Tôi đã quyết định chống lại một phương pháp tính toán hình ảnh ban đầu cần có vũ khí hạng nặng (phát hiện góc, trích xuất tính năng, lượng tử màu ...) vì ban đầu tôi không chắc nó sẽ thực sự hữu ích. Bây giờ tôi nhận ra sự hội tụ là chậm (dù sao thì 1 phút là chấp nhận được nhưng dù sao nó cũng chậm) và tôi có thể cố gắng cải thiện điều đó.

Vòng lặp phù hợp chính được lấy cảm hứng lỏng lẻo từ thuật toán phối màu Direct Binary Seach (trong đó các pixel được hoán đổi hoặc lật ngẫu nhiên cho đến khi thu được một halftone tốt hơn). Tính toán năng lượng là một khoảng cách trung bình bình phương gốc đơn giản, nhưng trước tiên tôi thực hiện bộ lọc trung bình 5x5 trên ảnh gốc. Một vệt mờ Gaussian có thể thể hiện tốt hơn hành vi của mắt người, nhưng tôi không muốn mất các cạnh sắc nét. Tôi cũng đã quyết định chống lại mô phỏng ủ hoặc các phương pháp khó điều chỉnh khác vì tôi không có nhiều tháng để hiệu chỉnh quy trình. Do đó, cờ "chất lượng" chỉ đại diện cho số lần lặp được thực hiện trên mỗi điểm trước khi bộ mã hóa kết thúc.

http://caca.zoy.org/raw-attachment/wiki/img2twit/Mona_Lisa_scaled.jpg http://caca.zoy.org/raw-attachment/wiki/img2twit/twitter2.png

苉 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗 憗激 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙 躙绒 酯

Mặc dù không phải tất cả các hình ảnh đều nén tốt, tôi rất ngạc nhiên với kết quả và tôi thực sự tự hỏi những phương pháp khác tồn tại có thể nén một hình ảnh thành 250 byte.

Tôi cũng có những bộ phim nhỏ về sự tiến hóa của trạng thái bộ mã hóa từ trạng thái ban đầu ngẫu nhiêntừ trạng thái ban đầu "tốt" .

Chỉnh sửa : đây là cách phương thức nén so sánh với JPEG. Ở bên trái, hình ảnh trên 536 byte của Jamoes. Ở bên phải, Mona Lisa đã nén xuống 534 byte bằng phương pháp được mô tả ở đây (các byte được đề cập ở đây đề cập đến byte dữ liệu, do đó bỏ qua các bit bị lãng phí bằng cách sử dụng các ký tự Unicode):

http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona.jpg http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona2.png

Chỉnh sửa : chỉ cần thay thế văn bản CJK bằng các phiên bản mới nhất của hình ảnh.


Tôi thực sự không cần phải có khả năng chạy mã (tôi đặt phần về việc chạy nó trong hướng dẫn, như một gợi ý, không phải là các quy tắc); Tôi muốn có thể chạy nó, nhưng tôi sẽ đánh giá điều này nhiều hơn về chất lượng của hình ảnh bạn tạo, mã và bất kỳ thủ thuật hoặc thuật toán thú vị nào. Nếu tôi muốn chạy nó và nó yêu cầu các gói tôi không có hoặc không muốn cài đặt trên hệ thống chính của mình, tôi có thể khởi động một phiên bản Amazon EC2 và cài đặt nó. Miễn là bạn đang làm việc với các thư viện được đóng gói cho một trong những phân phối chính, tôi sẽ có thể chạy nó. Hãy sử dụng CGAL.
Brian Campbell

2
Được rồi, đây là giải pháp của tôi (mã nguồn): caca.zoy.org/browser/libpipi/trunk/examples/img2twit.cpp nỗ lực giải thích của tôi và một vài ví dụ đang ở caca.zoy.org/wiki/img2twit
sam hocevar

2
Tôi thực sự thích giải pháp của bạn. Bạn nên thử giảm số lượng giá trị được gán cho kênh màu xanh lam vì mắt người không thể phân giải màu xanh rất tốt: nfggames.com/games/ntsc/visual.shtm ; điều này sẽ cho phép bạn có nhiều chi tiết hơn với chi phí của một số thông tin màu bị mất. Hoặc có lẽ gán nó cho màu xanh lá cây?
rpetrich

5
Điểm tốt. Tôi đã thử một vài biến thể của ý tưởng này (xem các bình luận trước định nghĩa RANGE_X) nhưng không kỹ lưỡng lắm. Như bạn có thể thấy, sử dụng 5 giá trị màu xanh thay vì 6 đã tăng ít hơn một chút so với sử dụng 7 giá trị màu xanh lá cây. Tôi đã không thử làm cả hai sự lười biếng. Một vấn đề khác tôi có là tôi không có chức năng lỗi rất tốt. Tôi hiện đang sử dụng ∑ (r² + g² + b²) / 3, hoạt động tốt. Tôi đã thử (0.299∆r² + 0.587∆g² + 0.114∆b²), dựa trên (không có lý do vật lý) trên thành phần Y của YUV, nhưng nó quá khoan dung với các lỗi màu xanh. Tôi sẽ cố gắng tìm các bài báo về vấn đề này.
sam hocevar

2
@rpetrich: Tôi đã sửa đổi chương trình để làm cho nó tăng phạm vi r / g / b một cách linh hoạt miễn là có đủ bit. Điều này đảm bảo rằng chúng ta không bao giờ lãng phí quá 13 bit trong toàn bộ dòng bit (nhưng trong thực tế, nó thường là 1 hoặc 2). Và hình ảnh trông hơi tốt hơn.
sam hocevar

45

Dưới đây không phải là một đệ trình chính thức, vì phần mềm của tôi đã không được điều chỉnh theo bất kỳ cách nào cho nhiệm vụ được chỉ định. DLI có thể được mô tả như là một codec hình ảnh mất mục đích chung tối ưu hóa. Đó là trình giữ bản ghi PSNR và MS-SSIM để nén hình ảnh và tôi nghĩ sẽ rất thú vị khi xem cách nó thực hiện cho tác vụ cụ thể này. Tôi đã sử dụng hình ảnh Mona Lisa tham chiếu được cung cấp và thu nhỏ nó xuống 100x150 sau đó sử dụng DLI để nén nó thành 344 byte.

Mona Lisa DLI http://i40.tinypic.com/2md5q4m.png

Để so sánh với các mẫu nén JPEG và IMG2TWIT, tôi đã sử dụng DLI để nén hình ảnh thành 534 byte. JPEG là 536 byte và IMG2TWIT là 534 byte. Hình ảnh đã được thu nhỏ lên đến cùng kích thước để dễ so sánh. JPEG là hình ảnh bên trái, IMG2TWIT là trung tâm và DLI là hình ảnh bên phải.

So sánh http://i42.tinypic.com/302yjdg.png

Hình ảnh DLI quản lý để giữ một số đặc điểm trên khuôn mặt, đáng chú ý nhất là nụ cười nổi tiếng :).


6
Giáo sư. Những điều trên nên được ghi có vào Dennis Lee, người đã gửi nó ban đầu. Tôi chỉ chỉnh sửa nó để nhúng các hình ảnh nội tuyến & liên kết đến tài liệu tham khảo mà tôi tìm thấy bởi Googling. Và tôi phải nói rằng, wow, tôi bị ấn tượng bởi sự nén. Tôi sẽ phải kiểm tra nén DLI.
Brian Campbell

1
Nhân tiện, tác giả DLI đề cập đến "thời gian xử lý dài". Vì tôi không thể chạy phần mềm của anh ấy, bạn có thể cho chúng tôi số thời gian nén thô không?
sam hocevar

1
Sử dụng AMD Athlon64 2.4Ghz, nén hình ảnh 100x150 Mona Lisa mất 38 giây và giải nén 6sec. Nén tới tối đa 251 byte khó khăn hơn, chất lượng đầu ra giảm đáng kể. Sử dụng hình ảnh Mona Lisa tham chiếu, tôi thu nhỏ nó xuống 60x91 sau đó sử dụng DLI để nén nó thành 243 byte (gần nhất với 251 mà không đi qua). Đây là đầu ra i43.tinypic.com/2196m4g.png Chi tiết không ở gần DLI 534 byte mặc dù bitrate chỉ bị giảm ~ 50%. Cấu trúc của hình ảnh đã được duy trì khá tốt tuy nhiên.

1
Quyết định làm cho việc so sánh các mẫu nén 250 byte dễ dàng hơn. DLI 243 byte đã được thu nhỏ và đặt bên cạnh mẫu IMG2TWIT. IMG2TWIT bên trái, DLI bên phải. Đây là hình ảnh i40.tinypic.com/30ndks6.png

1
DLI sử dụng một tham số chất lượng như JPEG, do đó, cần dùng thử và lỗi nếu muốn có kích thước đầu ra mục tiêu.

21

Tổng quan chung về giải pháp của tôi sẽ là:

  1. Tôi bắt đầu với việc tính toán lượng dữ liệu thô tối đa mà bạn có thể phù hợp với 140 ký tự utf8.
    • (Tôi giả sử utf8, đó là những gì trang web ban đầu tuyên bố twitter đã lưu trữ các tin nhắn của nó. Điều này khác với tuyên bố vấn đề ở trên, yêu cầu utf16.)
    • Sử dụng faq utf8 này , tôi tính toán rằng số bit tối đa bạn có thể mã hóa trong một ký tự utf8 là 31 bit. Để thực hiện việc này, tôi sẽ sử dụng tất cả các ký tự trong phạm vi U-04000000 - U-7FFFFFFF. (1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, có 31 x, do đó tôi có thể mã hóa tối đa 31 bit).
    • 31 bit nhân với 140 ký tự bằng 4340 bit. Chia số đó cho 8 để có 524,5 và làm tròn số đó xuống còn 542 byte .
    • (Nếu chúng tôi giới hạn bản thân ở utf16, thì chúng tôi chỉ có thể lưu trữ 2 byte cho mỗi ký tự, tương đương 280 byte).
  2. Nén hình ảnh xuống bằng cách sử dụng nén jpg tiêu chuẩn.
    • Thay đổi kích thước hình ảnh thành khoảng 50x50px, sau đó cố gắng nén nó ở các mức nén khác nhau cho đến khi bạn có một hình ảnh càng gần 542 byte càng tốt mà không cần đi qua.
    • Đây là một ví dụ về mona lisa được nén xuống còn 536 byte.
  3. Mã hóa các bit thô của hình ảnh nén thành các ký tự utf-8.
    • Thay thế mỗi x theo các byte sau: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, bằng các bit từ hình ảnh.
    • Phần này có lẽ sẽ là phần mà phần lớn mã cần được viết, bởi vì không có bất cứ thứ gì hiện đang tồn tại mà thực hiện điều này.

Tôi biết rằng bạn đã yêu cầu mã, nhưng tôi không thực sự muốn dành thời gian để thực sự viết mã này. Tôi hình dung rằng một thiết kế hiệu quả ít nhất có thể truyền cảm hứng cho người khác viết mã này.

Tôi nghĩ lợi ích chính của giải pháp đề xuất của tôi là nó đang sử dụng lại càng nhiều công nghệ hiện có càng tốt. Có thể rất vui khi thử viết một thuật toán nén tốt, nhưng có đảm bảo sẽ có một thuật toán tốt hơn ngoài kia, rất có thể được viết bởi những người có bằng cấp về toán cao hơn.

Một lưu ý quan trọng khác là nếu quyết định rằng utf16 là mã hóa ưa thích, thì giải pháp này sẽ sụp đổ. jpeg không thực sự hoạt động khi được nén xuống 280 byte. Mặc dù, có thể có một thuật toán nén tốt hơn jpg cho tuyên bố vấn đề cụ thể này.


Bây giờ tôi đang làm việc, nhưng tôi chắc chắn sẽ thực hiện giải pháp này khi về nhà.
Paulo Santos

2
Từ thử nghiệm của tôi, có vẻ như UTF-16 thực sự là cách Twitter đếm các ký tự; Các ký tự BMP được tính là 1 và các ký tự mặt phẳng cao hơn được tính là 2. Nó không được ghi lại, nhưng đó là cách bộ đếm ký tự JavaScript của chúng được tính khi bạn nhập vào hộp nhập. Nó cũng được đề cập trong các ý kiến ​​trong chủ đề ban đầu. Tôi đã không thử gửi qua API để xem bộ đếm có bị hỏng hay không; nếu có, tôi sẽ cập nhật sự cố cho các ràng buộc thực tế. Tuy nhiên, bạn không có khả năng sử dụng UTF-8 tùy ý, vì nhiều chuỗi dài hơn mà bạn có thể mã hóa không phải là Unicode hợp lệ.
Brian Campbell

4
Sau khi thử nghiệm với API của họ, hóa ra họ đếm bằng các ký tự Unicode (điểm mã), chứ không phải đơn vị mã UTF-16 (đó là bộ đếm ký tự JavaScript đếm qua UTF-16, vì rõ ràng đó là phương thức độ dài JavaScript làm) . Vì vậy, bạn có thể có thêm một chút thông tin trong đó; các ký tự Unicode hợp lệ nằm trong phạm vi U + 0000 đến U + 10FFFF (nhiều hơn 20 bit cho mỗi ký tự; 2 ^ 20 + 2 ^ 16 giá trị có thể cho mỗi ký tự). UTF-8 cho phép mã hóa nhiều giá trị hơn mức cho phép trong Unicode, vì vậy nếu bạn tự giới hạn ở Unicode, bạn có thể nhận được khoảng 350 byte không gian, chứ không phải 542.
Brian Campbell

3
Đó là lisa mona 536 byte trông tốt đáng ngạc nhiên, với độ nén cực cao!
Chris

3
Hiện tại chúng tôi có thể mã hóa 129.775 ký tự Unicode khác nhau (được gán, không kiểm soát, không riêng tư). Nếu chúng ta giới hạn bản thân trong tập hợp con đó, thì tổng cộng là 2377 bit, hoặc 297 byte. Mã ở đây: porg.es/blog/what-can-we-fit-in-140-char character
porges

20

Được rồi, tôi đến trễ trò chơi, nhưng tuy nhiên tôi đã thực hiện dự án của mình.

Đó là một thuật toán di truyền đồ chơi sử dụng các vòng tròn đầy màu sắc mờ để tạo lại hình ảnh ban đầu.

Đặc trưng:

  • Lua nguyên chất. Chạy bất cứ nơi nào có trình thông dịch Lua chạy.
  • sử dụng định dạng P3 netpbm
  • đi kèm với một bộ bài kiểm tra đơn vị toàn diện
  • giữ nguyên kích thước hình ảnh gốc

Sai lầm:

  • chậm
  • tại giới hạn không gian này, nó chỉ giữ lại bảng màu cơ bản của hình ảnh ban đầu và một phác thảo chung về một vài tính năng của chúng.

Đây là một twit ví dụ đại diện cho Lena: 犭 楊 谷 杌 蒝岂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂 掂虲 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙 兙廩 焛 严 啘 刱 垫 仔

lena gốc mã hóa Lena

Mã này nằm trong kho lưu trữ Mercurial tại bitbucket.org. Kiểm tra http://bitbucket.org/tkadlubo/circles.lua


2
Tuyệt vời! Tạo hình ảnh gọn gàng, nghệ thuật. Tôi rất vui vì mọi người vẫn đang làm việc này; thật vui khi thấy tất cả các cách tiếp cận khác nhau.
Brian Campbell

1
Tôi muốn thấy cái này được sử dụng giống như một lớp phủ trong suốt trên bản gốc, mang lại hiệu ứng như hiệu ứng bokeh.
Nick Radford

19

Sau đây là cách tiếp cận vấn đề của tôi và tôi phải thừa nhận rằng đây là một dự án khá thú vị để thực hiện, nó chắc chắn nằm ngoài lĩnh vực công việc bình thường của tôi và đã cho tôi một cái gì đó mới để tìm hiểu.

Ý tưởng cơ bản đằng sau của tôi là như sau:

  1. Lấy mẫu xuống thang màu xám của hình ảnh sao cho có tổng cộng 16 sắc thái khác nhau
  2. Tạo hình RLE trên hình ảnh
  3. Gói kết quả vào các ký tự UTF-16
  4. Tạo mẫu RLE trên các kết quả được đóng gói để loại bỏ bất kỳ sự trùng lặp nào của các ký tự

Nó chỉ ra rằng điều này không hoạt động, nhưng chỉ trong một phạm vi hạn chế như bạn có thể nhìn thấy từ các hình ảnh mẫu bên dưới. Về đầu ra, phần tiếp theo là một tweet mẫu, đặc biệt cho hình ảnh Lena được hiển thị trong các mẫu.

乤 万 企 企 3伂 2 企 伂 5 企 倁 企 伂 쥹 皗 鞹 阹

Như bạn có thể thấy, tôi đã thử và giới hạn bộ ký tự một chút; tuy nhiên, tôi gặp phải vấn đề khi lưu trữ dữ liệu màu hình ảnh. Ngoài ra, sơ đồ mã hóa này cũng có xu hướng lãng phí một loạt các dữ liệu có thể được sử dụng cho thông tin hình ảnh bổ sung.

Về thời gian chạy, đối với hình ảnh nhỏ, mã cực kỳ nhanh, khoảng 55ms cho hình ảnh mẫu được cung cấp, nhưng thời gian không tăng với hình ảnh lớn hơn. Đối với hình ảnh tham chiếu Lena 512x512, thời gian chạy là 1182ms. Tôi nên lưu ý rằng tỷ lệ cược khá tốt là bản thân mã không được tối ưu hóa cho hiệu suất (ví dụ: mọi thứ đều được xử lý như Bitmap ) để thời gian có thể giảm xuống một chút sau khi tái cấu trúc.

Xin vui lòng cung cấp cho tôi bất kỳ đề xuất nào về những gì tôi có thể làm tốt hơn hoặc những gì có thể sai với mã. Danh sách đầy đủ về thời gian chạy và đầu ra mẫu có thể được tìm thấy tại vị trí sau: http://code-zen.info/twitterimage/

Cập nhật một

Tôi đã cập nhật mã RLE được sử dụng khi nén chuỗi tweet để xem lại cơ bản và nếu vậy hãy sử dụng mã đó cho đầu ra. Điều này chỉ hoạt động cho các cặp giá trị số, nhưng nó lưu một vài ký tự dữ liệu. Thời gian chạy ít nhiều giống với chất lượng hình ảnh, nhưng các tweet có xu hướng nhỏ hơn một chút. Tôi sẽ cập nhật biểu đồ trên trang web khi tôi hoàn thành thử nghiệm. Dưới đây là một trong những chuỗi tweet mẫu, một lần nữa cho phiên bản nhỏ của Lena:

乤 万 2 企 企伂 쥹

Cập nhật hai

Một bản cập nhật nhỏ khác, nhưng tôi đã sửa đổi mã để đóng gói các sắc thái màu thành các nhóm ba so với bốn, điều này sử dụng thêm một số không gian, nhưng trừ khi tôi thiếu một cái gì đó, điều đó có nghĩa là các ký tự "lẻ" không còn xuất hiện ở nơi màu đó dữ liệu là. Ngoài ra, tôi đã cập nhật nén thêm một chút để giờ đây nó có thể hoạt động trên toàn bộ chuỗi chứ không phải chỉ là khối đếm màu. Tôi vẫn đang thử nghiệm thời gian chạy, nhưng chúng dường như được cải thiện trên danh nghĩa; tuy nhiên, chất lượng hình ảnh vẫn như nhau. Phiên bản mới nhất của tweet Lena:

2 乤 万 乐 唂 2 3 企 8 企 5 企 倂 倃 伂 倁 グ 儁 2 伂 倃 ガ企 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂 伂嗉

Logo StackOverflow http://code-zen.info/twitterimage/images/stackoverflow-logo.bmp Hộp Cornell http://code-zen.info/twitterimage/images/cornell-box.bmp Lena http: // code-zen .info / twitterimage / hình ảnh / lena.bmp Mona Lisa http://code-zen.info/twitterimage/images/mona-lisa.bmp


1
Tuyệt, cảm ơn vì đã vào! Grayscale thực sự hoạt động khá tốt đối với hầu hết những thứ này, mặc dù Lena hơi khó để tìm ra. Tôi đã tìm kiếm nguồn của bạn nhưng có 404; bạn có thể chắc chắn rằng nó ở trên đó?
Brian Campbell

Kiểm tra kỹ nó ngay bây giờ, tôi đang cập nhật trang web để bạn có thể bắt gặp tôi giữa các bản cập nhật.
rjzii

Đúng, tôi có thể tải xuống ngay bây giờ. Bây giờ tất nhiên tôi cần phải tìm ra nếu tôi có thể lấy Mono để biên dịch nó.
Brian Campbell

Vâng! Hoạt động theo Mono, tôi đã biên dịch với "gmcs -r System.Drawing TwitterImage.cs Program.cs" và chạy với "mono TwitterImage.exe mã hóa lena.png lena.txt"
Brian Campbell

Mát mẻ! Tôi đã kiểm tra kỹ để đảm bảo các thư viện tôi đang sử dụng được liệt kê cho Mono, nhưng tôi chưa thực sự làm việc với Mono nên tôi không chắc liệu nó có hay không.
rjzii


12

Trong thử thách ban đầu, giới hạn kích thước được xác định là những gì Twitter vẫn cho phép bạn gửi nếu bạn dán văn bản của mình vào hộp văn bản của họ và nhấn "cập nhật". Vì một số người nhận thấy chính xác điều này khác với những gì bạn có thể gửi dưới dạng tin nhắn văn bản SMS từ điện thoại di động của mình.

Điều không được đề cập một cách rõ ràng (nhưng quy tắc cá nhân của tôi là gì) là bạn sẽ có thể chọn tin nhắn được tweet trong trình duyệt của mình, sao chép nó vào bảng tạm và dán nó vào trường nhập văn bản của bộ giải mã để nó có thể hiển thị. Tất nhiên bạn cũng có thể tự do lưu tin nhắn như một tập tin văn bản và đọc nó trở lại hoặc viết một công cụ truy cập API Twitter và lọc ra bất kỳ thông điệp mà trông giống như một mã hình ảnh (đánh dấu đặc biệt ai? Nháy mắt nháy mắt ). Nhưng quy tắc là thông điệp phải được thông qua Twitter trước khi bạn được phép giải mã nó.

Chúc may mắn với 350 byte - Tôi nghi ngờ rằng bạn sẽ có thể sử dụng chúng.


1
Có, tôi đã thêm một phiếu điểm cho biết rằng các hạn chế chặt chẽ hơn đối với bộ ký tự được ưu tiên, nhưng không bắt buộc. Tôi muốn có một quy tắc yêu cầu các tin nhắn đi qua Twitter không bị ảnh hưởng, nhưng sẽ mất rất nhiều thử nghiệm và lỗi để tìm ra các chi tiết chính xác của những gì hoạt động và tôi muốn để lại một chút thời gian để cho phép sử dụng sáng tạo không gian mã. Vì vậy, yêu cầu duy nhất trong thử thách của tôi là 140 ký tự Unicode hợp lệ. Nhân tiện, cảm ơn bạn đã ghé qua! Tôi thực sự thích giải pháp của bạn, và muốn xem liệu có bất kỳ kibitzers nào thực sự có thể cải thiện nó không.
Brian Campbell

12

Đăng một hình ảnh đơn sắc hoặc màu xám sẽ cải thiện kích thước của hình ảnh có thể được mã hóa vào không gian đó vì bạn không quan tâm đến màu sắc.

Có thể làm tăng thêm thách thức để tải lên ba hình ảnh mà khi kết hợp lại sẽ cho bạn một hình ảnh đầy màu sắc trong khi vẫn duy trì một phiên bản đơn sắc trong mỗi hình ảnh riêng biệt.

Thêm một số nén vào ở trên và nó có thể bắt đầu tìm kiếm khả thi ...

Đẹp!!! Bây giờ các bạn đã khơi gợi sự quan tâm của tôi. Không có công việc sẽ được thực hiện trong phần còn lại của ngày ...


9
s / đạt đỉnh / piqued / g
eleven81

1
Tôi thích ý tưởng về ba hình ảnh, có thể thực hiện một ý tưởng như vậy lên twitter và kết quả sẽ khá tốt.
Makis

9

Về phần mã hóa / giải mã của thách thức này. cơ sở16b.org là nỗ lực của tôi để chỉ định một phương pháp tiêu chuẩn để mã hóa dữ liệu nhị phân một cách an toàn và hiệu quả trong các mặt phẳng Unicode cao hơn.

Một số tính năng :

  • Chỉ sử dụng các vùng người dùng riêng của Unicode
  • Mã hóa tối đa 17 bit cho mỗi ký tự; hiệu quả gấp gần ba lần so với Base64
  • Một triển khai Javascript tham chiếu về mã hóa / giải mã được cung cấp
  • Một số mã hóa mẫu được bao gồm, bao gồm Twitter và Wordpress

Xin lỗi, câu trả lời này đến quá muộn cho cuộc thi ban đầu. Tôi bắt đầu dự án một cách độc lập với bài đăng này, mà tôi đã khám phá được một nửa trong đó.


8

Ý tưởng lưu trữ một loạt các hình ảnh tham khảo là thú vị. Sẽ là quá sai khi lưu trữ 25Mb hình ảnh mẫu và bộ mã hóa thử và soạn một hình ảnh bằng cách sử dụng các bit của những hình ảnh đó? Với một ống cực nhỏ như vậy, máy móc ở hai đầu là cần thiết sẽ lớn hơn nhiều so với khối lượng dữ liệu đi qua, vậy sự khác biệt giữa 25Mb mã và 1Mb mã và 24Mb dữ liệu hình ảnh là gì?

(lưu ý các nguyên tắc ban đầu loại trừ việc hạn chế đầu vào cho các hình ảnh đã có trong thư viện - Tôi không gợi ý điều đó).


1
Điều đó sẽ ổn, miễn là bạn có một lượng dữ liệu cố định, hữu hạn ở một trong hai điểm cuối. Tất nhiên, bạn sẽ cần chứng minh rằng nó hoạt động với các hình ảnh không có trong tập huấn luyện, giống như bất kỳ vấn đề quy trình ngôn ngữ tự nhiên thống kê nào. Tôi muốn thấy một cái gì đó có một cách tiếp cận thống kê để mã hóa hình ảnh.
Brian Campbell

16
Tôi, trước hết, rất thích thấy Mona Lisa làm lại chỉ bằng cách sử dụng nghệ thuật quạt của Boba Fett làm nguồn.
Nosredna

Tôi đồng ý - cách tiếp cận photomosaic dường như nằm trong các quy tắc & sẽ cực kỳ thú vị khi thấy ai đó đâm vào.
Trả lời

8

Ý tưởng ngu ngốc, nhưng sha1(my_image)sẽ dẫn đến một đại diện "hoàn hảo" của bất kỳ hình ảnh nào (bỏ qua va chạm). Vấn đề rõ ràng là quá trình giải mã đòi hỏi số lượng vũ lực không phù hợp ..

Đơn sắc 1 bit sẽ dễ dàng hơn một chút .. Mỗi pixel trở thành 1 hoặc 0, do đó bạn sẽ có 1000 bit dữ liệu cho hình ảnh 100 * 100 pixel. Vì hàm băm SHA1 có 41 ký tự, chúng tôi có thể ghép ba thành một tin nhắn, chỉ cần buộc 2 bộ 3333 bit và một bộ 3334 (mặc dù điều đó có thể vẫn còn không phù hợp)

Nó không chính xác thực tế. Ngay cả với hình ảnh 1 bit 100 * 100px có độ dài cố định cũng có .., giả sử tôi không tính toán sai, kết hợp 49995000 hoặc 16661667 khi chia thành ba.

def fact(maxu):
        ttl=1
        for i in range(1,maxu+1):
                ttl=ttl*i
        return ttl

def combi(setsize, length):
    return fact(length) / (fact(setsize)*fact(length-setsize))

print (combi(2, 3333)*2) + combi(2, 3334)
# 16661667L
print combi(2, 10000)
# 49995000L

10
Vấn đề với sha1 (my_image) là nếu bạn dành thời gian để cưỡng bức nó, có lẽ bạn sẽ tìm thấy nhiều người va chạm trước khi bạn tìm thấy hình ảnh thật; và tất nhiên, vũ phu buộc sha1 là không thể tính toán được.
Brian Campbell

5
Thậm chí tốt hơn nén SHA1: thuật toán nén "flickr" của tôi! Bước 1: tải hình ảnh lên flickr. Bước 2: đăng một liên kết đến nó trên twitter. Tadda! Chỉ có 15 byte sử dụng!
niXar

2
niXar: Không, quy tắc 3.4: "Quá trình giải mã có thể không có quyền truy cập vào bất kỳ đầu ra nào khác của quá trình mã hóa ngoài đầu ra được chỉ định ở trên; nghĩa là bạn không thể tải lên hình ảnh ở đâu đó và xuất URL cho quá trình giải mã tải về, hoặc bất cứ điều gì ngớ ngẩn như thế. "
dbr

6
Tôi biết, tôi đã bị mỉa mai.
niXar


0

Ý tưởng: Bạn có thể sử dụng một phông chữ như một bảng màu? Cố gắng phá vỡ một hình ảnh trong một loạt các vectơ cố gắng mô tả chúng với sự kết hợp của các bộ vectơ (mỗi ký tự về cơ bản là một tập các vectơ). Đây là sử dụng phông chữ như một từ điển. Ví dụ, tôi có thể sử dụng al cho một đường thẳng đứng và một - cho một đường ngang? Chỉ là một ý tưởng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.