पर्ल, 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
फ़ाइल का आकार 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
।
माइकल के जवाब के लिए धन्यवाद :
बहुत सारी युक्तियों के साथ वादिम की टिप्पणी के लिए धन्यवाद :
use String::CRC32;
से छोटा है use Digest::CRC crc32;
।
y///c-4
से छोटा है -4+y///c
।
- अब स्कैन लाइन का निर्माण
CH*
मूल्य में पुनरावृत्ति के साथ टेम्पलेट द्वारा किया जाता है।
$i
मान संदर्भ का उपयोग करके निकालना ।
- चंक प्रकारों के लिए तार के बजाय नंगे शब्द।
-p
स्पेस सेपरेटर के मिलान के साथ STDIN इनपुट लाइन (विकल्प ) का मिलान करके अब पढ़े गए विकल्प / /
। तब पहला विकल्प होता है $`
और दूसरा तर्क अंदर जाता है $'
।
- विकल्प
-p
भी स्वचालित रूप से प्रिंट करता है $_
।
"\cZ"
से छोटा है "\x1a"
।
बेहतर संपीड़न
कोड आकार की कीमत पर छवि डेटा को और अधिक संपीड़ित किया जा सकता है, यदि फ़िल्टरिंग लागू किया जाता है।
FFFF0FF
200
832 बाइट्स के लिए अनफ़िल्टर्ड फ़ाइल का आकार
फ़िल्टर 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
आगे संपीड़ित नहीं कर सकता)।
999x999
फ़ाइल में 30720 से अधिक पिक्सेल होते हैं, जिससे यह आत्म-विरोधाभासी लगता है।