खरोंच से एक ठोस पीएनजी उत्पादन


11

इनपुट : आरजीबीए हेक्स रंग c(पूर्व FFFF00FF) और एक पूर्णांक> 0 और <1000 n(पूर्व 200)।

आउटपुट : कच्चे एक PNG फ़ाइल का बाइट्स ऐसी है कि जब उत्पादन एक फ़ाइल को बचाया और एक छवि दर्शक में खोला जाता है, एक nसे nरंग से भरा छवि cप्रदर्शित होता है।

विशिष्टता : आपका कार्यक्रम बिल्कुल आउटपुट होना चाहिए :

  • पीएनजी हेडर ( 89504E470D0A1A0Aहेक्स में)
  • IHDRइन विशिष्टताओं वाला एक हिस्सा:
    • चौड़ाई: पिछला इनपुट n
    • ऊंचाई: पिछले इनपुट n
    • थोड़ी गहराई: 8( RGBA)
    • रंग प्रकार: 6(अल्फा के साथ truecolor)
    • संपीड़न विधि: 0
    • फिल्टर विधि: 0
    • जिल्द विधि: 0
  • एक या अधिक IDATविखंडू जिसमें छवि डेटा (रंग की एक ठोस छवि पहले इनपुट c); संकुचित या असम्पीडित हो सकता है
  • एक IENDछवि अंत हिस्सा

विकीपीडिया पर , W3 साइट पर या Google खोज के माध्यम से और अधिक विवरण उपलब्ध हैं।

प्रतिबंध :

  • आप किसी भी प्रकार की छवियों के साथ काम करने के लिए डिज़ाइन की गई किसी भी छवि लाइब्रेरी या फ़ंक्शन का उपयोग नहीं कर सकते हैं।
  • आपका प्रोग्राम 3 मिनट से कम समय में चलना चाहिए और सभी इनपुट्स (स्वच्छता जांच) के लिए 10 एमबी के तहत एक फ़ाइल का उत्पादन करना चाहिए।
  • यह , इसलिए बाइट्स में सबसे छोटा कोड जीत जाएगा!

आप कहते हैं कि फ़ाइल पूरी तरह से असम्पीडित हो सकती है, लेकिन तब यह सभी इनपुट के लिए 30kB से कम होनी चाहिए। एक 999x999फ़ाइल में 30720 से अधिक पिक्सेल होते हैं, जिससे यह आत्म-विरोधाभासी लगता है।
पीटर टेलर

@PeterTaylor एचएम, किसी कारण से मुझे लगा कि 30 केबी पर्याप्त से अधिक था। पता नहीं मैं क्या सोच रहा था ... संपादित किया। (और मैं केवल ने कहा कि आप या संपीड़न का उपयोग नहीं हो सकता है, तुम जो भी चाहते हैं।)
दरवाज़े

चौड़ाई: 4 बाइट्स ऊँचाई: 4 बाइट्स बिट गहराई: 1 बाइट रंग प्रकार: 1 बाइट संपीड़न विधि: 1 बाइट फ़िल्टर विधि: 1 बाइट
इंटरलेस

@technosaurus ... उम, क्या?
दरवाज़े

1
आपका उदाहरण सही नहीं है: थोड़ी गहराई: 8 (RRGGBBAA)। बिट गहराई 8 (RGBA) नहीं है (RRGGBBAA)।
ग्लेन रैंडर्स-पीरसन

जवाबों:


6

पर्ल, 181

/ /;use String::CRC32;use Compress::Zlib;sub k{$_=pop;pack'Na*N',y///c-4,$_,crc32$_}$_="\x89PNG\r\n\cZ\n".k(IHDR.pack NNCV,$',$',8,6).k(IDAT.compress pack('CH*',0,$`x$')x$').k IEND

आकार 180 बाइट्स है और विकल्प -pकी आवश्यकता है (+1)। इसके बाद स्कोर 181 है।

एसटीडीआईएन के माध्यम से दलीलें एक पंक्ति में दी जाती हैं, जो एक स्थान, रंग को हेक्स मान (16 वर्ण) और चौड़ाई / ऊंचाई के लिए पिक्सल की संख्या के अनुसार अलग किया जाता है, जैसे:

 echo "FFFF00FF 200" | perl -p solidpng.pl >yellow200.png

yellow200.png

फ़ाइल का आकार 832 बाइट्स है। एक ही रंग के साथ अधिकतम आकार की छवि (n = 999) में 6834 बाइट्स (10 एमबी से नीचे का रास्ता) है।

समाधान दो पुस्तकालयों का उपयोग करता है:

  • use Digest::CRC crc32; chunk सिरों पर CRC32 मूल्यों के लिए।
  • use IO::Compress::Deflate deflate; छवि डेटा को संपीड़ित करने के लिए।

दोनों पुस्तकालय छवियों से संबंधित नहीं हैं।

Ungolfed:

# Perl option "-p" adds the following around the program:
#     LINE:
#     while (<>) {
#         ... # the program goes here
#     } continue {
#         print or die "-p destination: $!\n";

/ /;    # match the separator of the arguments in the input line
        # first argument, color in hex:  $`
        # second argument, width/height: $'                              #'

# load the libraries for the CRC32 fields and the data compression
use String::CRC32;
use Compress::Zlib;

# function that generates a PNG chunk:
#   N (4 bytes, big-endian: data length
#   N:                      chunk type
#   a* (binary data):       data
#   N:                      CRC32 of chunk type and data
sub k {
    $_ = pop; # chunk data including chunk type and
              # excluding length and CRC32 fields
    pack 'Na*N',
        y///c - 4,   # chunk length                                      #/
                     # netto length without length, type, and CRC32 fields
        $_,          # chunk type and data
        crc32($_)    # checksum field
}

$_ =                      # $_ is printed by option "-p".
    "\x89PNG\r\n\cZ\n"    # PNG header
        # IHDR chunk: image header with
        #   width, height,
        #   bit depth (8), color type (6),
        #   compresson method (0), filter method (0), interlace method (0)
    . k('IHDR' . pack NNCV, $', $', 8, 6)
        # IDAT chunk: image data
    . k('IDAT' .
          compress        # compress/deflate data
          pack('CH*',     # scan line with filter byte
              0,          # filter byte: None
              ($` x $')   # pixel data for one scan line                 #'`
          ) x $'          # n lines                                      #'
      )
        # IHDR chunk: image end
    . k('IEND');

संपादित करता

  • use IO::Compress::Deflate':all';द्वारा प्रतिस्थापित किया जाता है use Compress::Zlib;। उत्तरार्द्ध compressडिफ़ॉल्ट रूप से डिफ्लेट फ़ंक्शन को निर्यात करता है । फ़ंक्शन को तर्कों के रूप में संदर्भों की आवश्यकता नहीं होती है और यह सीधे परिणाम भी देता है। यह चर से छुटकारा पाने की अनुमति देता है $o

माइकल के जवाब के लिए धन्यवाद :

  • फ़ंक्शन k: फ़ंक्शन में पहली बार packटेम्पलेट का उपयोग करके हटाया जा सकता है ।Na*Npack

  • packNNCVचार मूल्यों वाला टेम्पलेट NNC3nछह मूल्यों के साथ अनुकूलन करता है।

बहुत सारी युक्तियों के साथ वादिम की टिप्पणी के लिए धन्यवाद :

  • use String::CRC32;से छोटा है use Digest::CRC crc32;
  • y///c-4से छोटा है -4+y///c
  • अब स्कैन लाइन का निर्माण CH*मूल्य में पुनरावृत्ति के साथ टेम्पलेट द्वारा किया जाता है।
  • $iमान संदर्भ का उपयोग करके निकालना ।
  • चंक प्रकारों के लिए तार के बजाय नंगे शब्द।
  • -pस्पेस सेपरेटर के मिलान के साथ STDIN इनपुट लाइन (विकल्प ) का मिलान करके अब पढ़े गए विकल्प / /। तब पहला विकल्प होता है $`और दूसरा तर्क अंदर जाता है $'
  • विकल्प -pभी स्वचालित रूप से प्रिंट करता है $_
  • "\cZ"से छोटा है "\x1a"

बेहतर संपीड़न

कोड आकार की कीमत पर छवि डेटा को और अधिक संपीड़ित किया जा सकता है, यदि फ़िल्टरिंग लागू किया जाता है।

  • FFFF0FF 200832 बाइट्स के लिए अनफ़िल्टर्ड फ़ाइल का आकार

  • फ़िल्टर Sub(क्षैतिज पिक्सेल अंतर): 560 बाइट्स

    $i = (                            # scan line:
             "\1"                     # filter "Sub"
             . pack('H*',$c)          # first pixel in scan line
             . ("\0" x (4 * $n - 4))  # fill rest of line with zeros
          ) x $n;                     # $n scan lines
  • Subपहली पंक्ति के Upलिए और शेष लाइनों के लिए फ़िल्टर करें : 590 बाइट्स

    $i = # first scan line
         "\1"                     # filter "Sub"
         . pack('H*',$c)          # first pixel in scan line
         . ("\0" x (4 * $n - 4))  # fill rest of line with zeros
         # remaining scan lines 
         . (
               "\2"               # filter "Up"  
               . "\0" x (4 * $n)  # fill rest of line with zeros
           ) x ($n - 1);
  • पहले अनफ़िल्टर्ड लाइन, फिर फ़िल्टर करें Up: 586 बाइट्स

    $i = # first scan line
         pack('H*', ("00" . ($c x $n)))  # scan line with filter byte: none
         # remaining scan lines 
         . (
               "\2"               # filter "Up"
               . "\0" x (4 * $n)  # fill rest of line with zeros
           ) x ($n - 1);
    
  • भी Compress::Zlibट्यून किया जा सकता है; उच्चतम संपीड़न स्तर compressदो बाइट्स की लागत पर फ़ंक्शन में संपीड़न स्तर के लिए अतिरिक्त विकल्प द्वारा निर्धारित किया जा सकता है :

    compress ..., 9;

    yellow200.pngफ़िल्टरिंग के बिना उदाहरण के फ़ाइल का आकार 832 बाइट्स से घटकर 472 बाइट्स हो जाता है। Subफ़िल्टर के साथ उदाहरण के लिए लागू , फ़ाइल का आकार 560 बाइट्स से 445 बाइट्स तक सिकुड़ता है ( pngcrush -bruteआगे संपीड़ित नहीं कर सकता)।


शानदार उत्तर (हमेशा की तरह), लेकिन गोल्फ आगे जा सकता है - मुझे 202, + 1 मिलता है -p। माइकल के उत्तर ( NA*Nऔर NNCVटेम्प्लेट) में अंतर्दृष्टि के अलावा , - String::CRC32डिफ़ॉल्ट रूप से निर्यात, y///c-4ठीक है, CH*टेम्प्लेट, $iचला गया \cZ, नंगे पासवर्ड ठीक हैं, -pऔर / /;तर्क को आधार और पोस्टमैच में रखता है। मुझे आश्चर्य है कि अगर मैंने कुछ याद किया और स्कोर 200 से नीचे जा सकता है :)
user2846289

1
@VadimR: उपयोगी सुझावों के लिए बहुत धन्यवाद। मैं इसे आगे भी गोल्फ कर सकता था use Compress::Zlib;और below 10% 200 से नीचे पाया।
हेइको ओबर्डिएक

5

PHP 214

मैं PHP का विशेषज्ञ नहीं हूं, गोल्फिंग के लिए जगह है। सुझावों का स्वागत किया जाता है।

<?function c($d){echo pack("Na*N",strlen($d)-4,$d,crc32($d));}echo"\x89PNG\r\n\x1a\n";c("IHDR".pack("NNCV",$n=$argv[1],$n,8,6));c("IDATx^".gzdeflate(str_repeat("\0".str_repeat(hex2bin($argv[2]),$n),$n)));c("IEND");

PNG फ़ाइल बनाएं:

php png.php 20 FFFF00FF > output.png

बेस 64 स्ट्रीम जनरेट करें (अपने ब्राउज़र एड्रेस बार में रिजल्ट पेस्ट करें)

echo "data:image/png;base64,`php png.php 200 0000FFFF | base64`"

Ungolfed संस्करण:

<?php 

//function used to create a PNG chunck
function chunck($data) {
  return pack("Na*N", //write a big-endian integer, a string and another integer
    strlen($data)-4,     //size of data minus the 4 char of the type
    $data,               //data
    crc32($data));       //compute CRC of data
}

//png header
echo "\x89PNG\r\n\x1a\n"; 

//IHDR chunck
echo chunck("IHDR".pack("NNCV", //2 big-endian integer, a single byte and a little-endian integer
                   $n=$argv[1], $n,
                   8, 6)); //6 also write 3 zeros (little endian integer)

//IDAT chunck
//create a binary string of the raw image, each line begin with 0 (none filter)
$d = str_repeat("\0".str_repeat(hex2bin($argv[2]),$n),$n);
echo chunck("IDATx^".
       gzdeflate($d)); //compress raw data

//IEND chunck
echo chunck("IEND");

यह अब 214 है, है ना? और, मुझे गोल्फ और अन-गोल्फ दोनों संस्करणों से कोई सही छवि नहीं मिल सकती है, लेकिन मेरे पास कोई PHP अनुभव नहीं है, इसलिए यदि यह हर किसी के लिए काम करता है, तो यह मुझे गलत कर रहा है।
user2846289

1
@VadimR, हाँ 214, आप सही कह रहे हैं। मैंने जाँच की है, उत्पन्न छवि मेरे लिए मान्य है।
माइकल एम।

मेरे लिए (मैं PHP 5.4.27.0 के साथ परीक्षण करता हूं), छवि 4 बाइट्स छोटी है - क्या दोषपूर्ण डेटा को एडलर -32 संलग्न नहीं किया जाना चाहिए? IE और क्रोम छवि को प्रदर्शित करने के लिए खुश हैं, जैसा कि एफएफ नहीं है। अलग-अलग ऐप इस छवि के साथ अलग-अलग व्यवहार करते हैं।
user2846289

4

पायथन, 252 बाइट्स

import struct,sys,zlib as Z
P=struct.pack
A=sys.argv
I=lambda i:P(">I",i)
K=lambda d:I(len(d)-4)+d+I(Z.crc32(d)&(2<<31)-1)
j=int(A[2])
print "\x89PNG\r\n\x1A\n"+K("IHDR"+P(">IIBI",j,j,8,6<<24))+K("IDAT"+Z.compress(("\0"+I(int(A[1],16))*j)*j))+K("IEND")

यह स्क्रिप्ट arvv से इनपुट लेती है। इस स्क्रिप्ट को कमांड लाइन से चलाएं, जैसेpython 27086.py deadbeef 999

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.