Làm cách nào tôi có thể lưu trữ siêu dữ liệu trò chơi trong tệp .png?


208

Spore cho phép các sinh vật do người chơi tạo ra được chia sẻ bằng cách xuất một .pngtệp. Đó .pnglà hình ảnh của sinh vật, nhưng nếu được nhập vào trò chơi, thông tin của sinh vật (như kết cấu, kích thước và hình dạng) cũng đi kèm với nó.

Làm thế nào tôi có thể thực hiện một tính năng như vậy?


5
Nên có điểm cao hơn nhiều, đó là một câu hỏi rất thú vị.
Pierre Arlaud

3
Kênh alpha có thể bị lạm dụng một phần cho việc này ...
Tobias Kienzler


1
Tôi nghĩ tốt hơn là lưu trữ dữ liệu này trong một tệp khác. Trong tệp này, cần có tên của tệp kết cấu có liên quan đến thực thể bạn muốn lưu trữ dữ liệu. Đầu tiên vì mục đích khám phá (định dạng png dành cho đồ họa - "Đồ họa mạng di động"), thứ hai: xem xét tình huống bạn muốn lưu trữ nhiều hình ảnh hơn với một thực thể, bạn chỉ cần thêm tham chiếu đến nó từ tệp tùy chỉnh đó. Bạn có thể sẽ gặp sự cố khi lưu trữ các hình ảnh khác nhau (kích thước khác nhau, độ sâu khác nhau, v.v.) trong một PNG.
luke1985

3
Kênh alpha đã được đề cập rất nhiều và dĩ nhiên PNGs hỗ trợ dữ liệu meta, nhưng tôi chỉ nghĩ rằng tôi chia sẻ một kỹ thuật tôi đã sử dụng - bước qua trái sang phải, từ trên xuống dưới và qua các kênh theo thứ tự cố định và làm tròn các giá trị theo tỷ lệ cược hoặc phát sinh - không quan trọng nếu nó tăng hay giảm. Thay đổi 1 trong BẤT K of kênh nào không tạo ra sự khác biệt đáng chú ý và trong hình ảnh 256x256 (tất nhiên là 4 bit cho mỗi pixel), bạn có thể lưu trữ dữ liệu 32KB ấn tượng. Nếu bạn cần nhiều hơn nữa, bạn có thể làm tròn đến% 4 thay vào đó - quá nhiều và nó bắt đầu trông giống như một tâm trí GIF cũ ..
Octopoid 11/2/2015

Câu trả lời:


56

Nếu tất cả những gì bạn thực sự cần là tệp PNG, rất có thể họ chỉ cần thêm thông tin vào tệp. Đây thực sự là một thực hành của Steganography . Rất nhiều lần, điều này được sử dụng để ẩn tải trọng hoặc tin nhắn bí mật trong những thứ dường như đối mặt với công chúng. Tuy nhiên, trong trường hợp này có khả năng phương pháp này là những gì đã được sử dụng. Stegongraphy điển hình sẽ tìm cách ẩn nội dung, nhưng không có lý do gì mà người ta không thể đơn giản nối dữ liệu ra khỏi hình ảnh vào cuối tệp và lấy nó.

Một số công cụ mã hóa dữ liệu này cho bạn, một tìm kiếm google đưa ra ít nhất cái nàycái này .

Một PNG có chữ ký byte $89khi bắt đầu, vì vậy có thể thông tin được chèn vào sau cấu trúc PNG và được phân tích đơn giản bởi trò chơi SPORE.

Tuy nhiên, nghiên cứu sâu hơn được đưa ra bởi các câu trả lời khác và tìm kiếm trên google cho thấy Spore thực sự chỉ sử dụng một phiên bản của Stegongraphy để ẩn thông tin trong các bit alpha. Với suy nghĩ này, chúng ta có thể loại trừ khả năng dữ liệu được nối thêm hoặc siêu dữ liệu.

Cần lưu ý rằng dữ liệu meta vẫn là một lựa chọn rất khả thi, nếu dữ liệu đang được phân tích cú pháp cục bộ. Nếu thông tin đó có thể được chia sẻ trên web hoặc được mã hóa lại, việc xuất không được đảm bảo để giữ tất cả thông tin của bạn. Khi dữ liệu pixel được sử dụng, nó có thể tồn tại trong các chuyển đổi không mất dữ liệu mà không gặp sự cố.


3
Theo như tôi biết, bào tử được lưu trữ siêu dữ liệu bên trong kênh alpha của PNG.
Tara

28
Tại sao nên sử dụng kênh alpha hoặc steganography khi PNG hỗ trợ các khối siêu dữ liệu tùy ý?
Russell Borogove

8
Lúc đầu, PNG A PNG có chữ ký byte "89", do đó rất có thể thông tin đã được chèn trước hoặc sau cấu trúc PNG và được phân tích đơn giản bởi trò chơi SPORE. Nếu đó là trường hợp, thì nó sẽ không ' t là một tập tin PNG nữa. Tức là người xem hình ảnh phổ biến sẽ không thể hiển thị nó.
Svick

3
@RussellBorogove một lý do khá chính đáng: nếu PNG được giải mã / mã hóa bởi thứ gì đó ngoài Spore, các khối siêu dữ liệu tùy ý có nhiều khả năng bị bỏ qua hoặc mất hơn so với dữ liệu hình ảnh thực tế. Mã hóa dữ liệu trong hình ảnh cải thiện khả năng nếu bạn có thể nhìn thấy nó, bạn có thể tải nó .
Tim S.

@svick Trên thực tế, tôi đã chơi với một tệp có cả PNG và RAR hợp lệ. Tiêu đề RAR bắt đầu sau PNG và các trình trích xuất RAR vẫn ổn. Nó có thể hoạt động tốt theo cách khác quá.
vỏ não

153

Các định dạng PNG có hỗ trợ cho các siêu dữ liệu nhiều hơn hoặc ít hơn tùy ý. Các tiêu chuẩn PNG định nghĩa một tập tin PNG, về cơ bản một loạt các khối, một số trong đó được yêu cầu (và chứa các dữ liệu hình ảnh). Những người khác, tuy nhiên, là tùy chọn. Ví dụ: có một đoạn để lưu trữ thông tin gamma hoặc dữ liệu biểu đồ.

Đặc biệt, có một tEXtđoạn có thể được sử dụng để lưu trữ các cặp văn bản khóa / giá trị tùy ý. Điều này có thể được sử dụng để vận chuyển xung quanh bất kỳ loại dữ liệu tùy ý nào bạn muốn, miễn là bạn có thể biểu thị dữ liệu đó dưới dạng văn bản (khá có khả năng).

Bạn sẽ cần một thư viện PNG cho phép bạn truy cập và thao tác các khối bổ sung này (chẳng hạn như thư viện tham chiếu ) hoặc bạn sẽ cần phải tự viết. Sau đó, vấn đề chỉ là chọn cách mã hóa dữ liệu bạn muốn dưới dạng cặp khóa / giá trị. Tôi muốn đề xuất như sau:

  • chọn các tên khóa có tiền tố với tên hoặc tên mã dự án của bạn để tạo ra một hệ thống "không gian tên" thô sơ và tránh xung đột tiềm ẩn với việc sử dụng dữ liệu của ứng dụng khác
  • đừng cố lưu trữ kết cấu thực tế theo cách này, lưu trữ các tham chiếu đến các kết cấu đó chỉ trong cơ sở dữ liệu tài sản của trò chơi của bạn
  • dữ liệu như sinh vật hoặc kích thước đối tượng, trọng lượng, et cetera - vô hướng đơn giản, về cơ bản - có thể được lưu trữ tầm thường

Để tạo ra một câu trả lời đầy đủ hơn, tôi cũng chỉ ra rằng có một cách tiếp cận khác (trước đây là câu trả lời của @Vaughn và @ Alexis): mã hóa dữ liệu bổ sung mà bạn muốn trực tiếp trong pixel hình ảnh của mình, phân phối dữ liệu của bạn các bit thứ tự thấp của các kênh màu. Cách tiếp cận này không yêu cầu sử dụng siêu dữ liệu bổ sung, có nghĩa là bạn có thể thực hiện hoàn toàn mà không cần dựa vào nó hoặc lo lắng về các chương trình bên ngoài xử lý không chính xác siêu dữ liệu đó. Nó cũng có một yếu tố "mát mẻ" rất cao và bởi vì bạn chỉ sử dụng các bit có thứ tự thấp, hình ảnh sẽ vẫn trông chính xác với mắt người. Tuy nhiên, điều đó có nghĩa là kích thước hình ảnh của bạn là yếu tố kiểm soát chính đối với lượng dữ liệu bạn có thể lưu trữ; nếu bạn cần thêm dung lượng, bạn cần phân bổ nhiều pixel hơn cho hình ảnh.

Như những người khác đã chỉ ra, quá trình này được gọi là steganography .


3
Người ta có thể chỉ cần gửi dữ liệu qua Base64 và lưu trữ dưới dạng một giá trị duy nhất
CodeInChaos

11
@ da4c30ff Thực tế như siêu dữ liệu, steganography có một yếu tố tuyệt vời về giả tưởng gián điệp mà đám đông chúng ta khó có thể cưỡng lại. Nếu tôi đang tự làm điều này, tôi sẽ sử dụng phương pháp được đề xuất của Josh Petrie cho khả năng mở rộng, nhưng tôi rất muốn sử dụng chức năng ghi ảnh để ẩn một tổng kiểm tra trong hình ảnh để xác minh rằng hình ảnh và văn bản thuộc về nhau - không phải vì Điều này hữu ích hoặc an toàn, nhưng chỉ vì nó mát mẻ. ;)
DMGregory

Chính xác thì văn bản của Ý có nghĩa gì ở đây? Chỉ ASCII (ký tự <= 127)? Bất kỳ byte nào ngoại trừ 0? Bất kỳ byte nào? Hay cái gì khác? (Điều này sẽ ảnh hưởng đến mã hóa bạn cần sử dụng để ghi dữ liệu nhị phân. Ví dụ: bạn có cần base64 hay không.)
svick

1
Tôi đã cập nhật câu trả lời với một liên kết đến tiêu chuẩn cho đoạn văn bản; nhưng về cơ bản, văn bản được hiểu theo ISO 8859-1 (8 bit, một byte, ký tự Latin-1).
Josh

51

Nhà phát triển của Monaco thực sự đã thực hiện một bài viết xuất sắc về cách cả họ và Spore hoàn thành việc này.

Tóm tắt cơ bản về những gì họ làm khá đơn giản:

  • Chuyển đổi dữ liệu của bạn thành nhị phân
  • Chuyển đổi hình ảnh mục tiêu của bạn thành một bitmap thô
  • Đi dọc theo các pixel của hình ảnh theo một số mẫu có thể dự đoán được (chúng chỉ đơn giản là thực hiện từ trái sang phải từ góc trên bên trái).
  • Viết một bit vào bit thứ tự thấp nhất của mỗi kênh màu của mỗi pixel
  • Xuất bitmap đã sửa đổi sang png một lần nữa

Đơn giản chỉ cần làm điều này ngược lại để lấy dữ liệu của bạn.

Ý tưởng cơ bản đằng sau quá trình này là có rất nhiều pixel trong một hình ảnh và các bit thứ tự thấp nhất của mỗi kênh màu không tạo ra sự khác biệt lớn . Ngoài ra, khoảng một nửa số bit bạn viết sẽ chỉ là những gì bit trong hình ảnh đã có. Những gì bạn nhận được về cơ bản là hình ảnh phù hợp, nhưng với các tạo tác kỳ lạ. Anh ấy dành thời gian để lưu ý rằng những đồ tạo tác này chỉ thực sự đáng chú ý nếu bạn thực sự xoay độ tương phản / bão hòa và phóng to. Tuy nhiên, anh ấy có hình ảnh nguồn với nhiều nhiễu.

Từ bài viết:

Lưu ý trong hình ảnh cuối cùng làm thế nào có một đường ngang hầu như không thấy rõ trong tiếng ồn. Đó là kết thúc của dữ liệu cấp. Điều này có nghĩa là tôi thực sự có thể điều chỉnh tất cả dữ liệu cấp độ thành hình ảnh 265x120 pixel, chỉ sử dụng bit có trọng số thấp nhất.

MỘT ĐỊA CHỈ NHANH CHÓNG:

Một cái gì đó tôi có thể làm và tôi tin rằng những người Spore cũng đã làm như vậy, thực sự sử dụng TẤT CẢ các bit màu trong các pixel trong suốt 100%. Vì các pixel đó trong suốt, nên bạn đặt chúng thành màu gì không quan trọng.

Tuy nhiên, tôi không thể làm điều này vì tôi đang sử dụng toàn bộ hình ảnh, điều đó có nghĩa là tôi không có pixel trong suốt để làm việc.

Tại sao lại ưu tiên kỹ thuật này hơn là chỉ lưu trữ nó trong siêu dữ liệu?

  • Thật là vui! :)
  • Các dịch vụ có thể thu thập siêu dữ liệu (có thể là tính năng bảo mật / bảo mật), nhưng không nên sử dụng các pixel của png trừ khi chúng có các yêu cầu lưu trữ hình ảnh mạnh mẽ (nhìn vào bạn, facebook). Nhưng nếu họ hoàn toàn tái xuất hình ảnh của bạn thì bạn không thể làm gì được.

Tín dụng bổ sung: để giảm mức độ đáng chú ý của nhiễu, bạn có thể sử dụng PRNG với một hạt giống cố định để chọn các pixel cần sửa đổi. Bạn cũng chỉ có thể sửa đổi một số kênh màu theo cách tương tự.


6
Có các thuật toán lập thể mạnh mẽ hơn so với điều chỉnh tỷ lệ hình ảnh / điều chỉnh màu sắc so với phương pháp Monaco. (Mặc dù họ thường lưu trữ dữ liệu ở mật độ thấp hơn đáng kể) Một ví dụ là watermarking sử dụng trong World of Warcraft ảnh chụp màn hình: ownedcore.com/forums/world-of-warcraft/...
DMGregory

@DMGregory Đẹp tìm! Thuật toán chính xác bạn chọn tất nhiên phải được quyết định bởi usecase cụ thể của bạn (không gian, độ bền, bí mật, v.v.).
Alexis Beingessner

1
Nghe có vẻ hay, đây là một ý kiến ​​tồi. Hình ảnh PNG sử dụng nén hình ảnh lossless ; loay hoay với các bit thấp của hình ảnh có thể sẽ làm cho tệp lớn hơn cùng lúc vì nó (hơi) làm giảm chất lượng hình ảnh. Hoàn toàn bất kỳ thông tin nào cũng có thể được mã hóa thành "văn bản", vì vậy sử dụng một đoạn siêu dữ liệu là cách rõ ràng chính xác để làm điều này; ai đó nghịch ngợm hình ảnh bit mà không thực sự cần steganography chỉ là popies wheelies.
dfeuer

1
@dfeuer - Rõ ràng cả Spore và Monaco đều đang sử dụng các khung trò chơi có một đường dẫn tải tài sản để loại bỏ .PNG xuống một bitmap trần, do đó, các siêu dữ liệu không thể vượt qua.
Russell Borogove

1
@dfeuer Tôi đã làm một số bài kiểm tra ngây thơ. Cách tiếp cận siêu dữ liệu dường như thêm khoảng 80% kích thước được thêm vào bởi cách tiếp cận tốc độ khi ghi 100kB bit ngẫu nhiên vào hình ảnh 1920x1080px. Đã thử nghiệm trên một hình ảnh trống và ảnh chụp màn hình máy tính để bàn. Không hẳn là một sự khác biệt thảm khốc, nhưng thịt siêu dữ liệu chắc chắn tốt hơn (và nhất quán hơn) nếu bạn thực sự quan tâm hơn 40kB. Lưu ý rằng siêu dữ liệu vẫn còn khá kém hiệu quả. Tôi đã đạt được 181kB khi viết 100kB dữ liệu! Có thể là phòng để tối ưu hóa cách chuỗi được mã hóa hoặc một cái gì đó.
Alexis Beingessner

7

Tôi đã tải xuống và kiểm tra một vài sinh vật bào tử từ Sporepedia. Từ những người tôi đã học được rằng:

  • Các hình ảnh không chứa thông tin ngoài dữ liệu hình ảnh tiêu chuẩn.
  • Dữ liệu tốc độ đã được lưu trữ mà không xem xét cho hình ảnh, người ta có thể tưởng tượng rằng các phần trong suốt được sử dụng riêng, nhưng chúng thì không.
  • Việc sử dụng lưu trữ phụ thuộc vào lượng thông tin cần lưu trữ, một số hình ảnh chỉ sử dụng bit quan trọng nhất để lưu trữ dữ liệu, một số sử dụng hai bit ít quan trọng nhất, một số có thể sử dụng nhiều hơn.
  • Định dạng Spore tránh sử dụng một bit trên một phần của hình ảnh, bit thay đổi ít quan trọng nhất trong toàn bộ hình ảnh, nếu sử dụng bit có ý nghĩa thứ hai ít nhất, nó được sử dụng trên toàn bộ hình ảnh. Điều này có lẽ được thực hiện bằng cách sử dụng đệm ngẫu nhiên. Điều này tránh sự thay đổi về chất lượng có thể gây khó chịu cho người xem hơn là tiếng ồn.
  • Tất cả bốn kênh được sử dụng như nhau, kênh độ mờ không được xử lý đặc biệt, do đó một số pixel trong suốt hơi mờ trong khi một số pixel mờ hơi trong suốt.

Điều đáng chú ý là đây chỉ là những gì Spore làm, nó là một phương pháp đặt sự đơn giản trước hầu hết các mối quan tâm khác.

Việc lựa chọn sử dụng chức năng ghi tốc độ thay vì khối dữ liệu bổ sung có nghĩa là dữ liệu sẽ tồn tại nếu hình ảnh được mã hóa lại, ví dụ như bởi một trang web, mặc dù nó sẽ không tồn tại theo tỷ lệ hoặc nén Jpeg.

Tôi nghĩ rằng sự thay thế nổi bật nhất thực sự là chỉ mã hóa một id trong hình ảnh và để dữ liệu thực tế được lưu trữ trên một máy chủ trung tâm nơi id này có thể được trao đổi để lấy dữ liệu sinh vật chính xác. Một id như vậy sẽ đủ ngắn để nó có thể được mã hóa theo định dạng tốc độ cho phép nén và chia tỷ lệ.

Những cải tiến đơn giản có thể có đối với định dạng Spore bao gồm:

  • Chỉ sử dụng hoặc thích sử dụng các giá trị màu của các pixel trong suốt, chúng không tạo ra sự khác biệt về thị giác.
  • Sử dụng kênh màu xanh nhiều hơn và kênh màu xanh lá cây ít hơn, màu xanh lam có tác động nhận thức thấp hơn đối với hình ảnh.
  • Giữ độ chói của từng pixel gần như không thay đổi và mã hóa dữ liệu theo sắc độ, một chút nhiễu trong tham số này hầu như không thể phát hiện được đối với con người.
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.