স্ক্র্যাচ থেকে একটি শক্ত পিএনজি আউটপুট করুন


11

ইনপুট : একটি আরজিবিএ হেক্স রঙ c(প্রাক্তন FFFF00FF) এবং একটি পূর্ণসংখ্য> 0 এবং <1000 n(প্রাক্তন 200)।

আউটপুট : পিএনজি ফাইলের কাঁচা বাইটগুলি যেমন যখন আউটপুট কোনও ফাইলে সংরক্ষণ করা হয় এবং চিত্র দর্শকের মধ্যে খোলা হয়, রঙে পূর্ণ চিত্র nদ্বারা প্রদর্শিত হয়।nc

নির্দিষ্টকরণ : আপনার প্রোগ্রামটি ঠিক আউটপুট করা উচিত :

  • একটি পিএনজি শিরোনাম ( 89504E470D0A1A0Aহেক্সে)
  • IHDRএই স্পেসিফিকেশন সমন্বিত একটি অংশ:
    • প্রস্থ: পূর্ববর্তী ইনপুট n
    • উচ্চতা: পূর্ববর্তী ইনপুট n
    • বিট গভীরতা: 8( RGBA)
    • রঙের ধরণ: 6(আলফার সাথে ট্রুয়েলর)
    • কম্প্রেশন পদ্ধতি: 0
    • ফিল্টার পদ্ধতি: 0
    • বিভাজন পদ্ধতি: 0
  • এক বা একাধিক IDATঅংশে চিত্রের ডেটা রয়েছে (বর্ণের পূর্বে একটি শক্ত চিত্র c); সংকুচিত বা সঙ্কুচিত হতে পারে
  • একটি IENDইমেজ শেষ অংশ

উইকিপিডিয়ায় , ডাব্লু 3 সাইটে অথবা গুগল অনুসন্ধানের মাধ্যমে আরও বিশদ উপলব্ধ ।

বিধিনিষেধসমূহ :

  • আপনি কোনও ধরণের চিত্রের সাথে কাজ করার জন্য ডিজাইন করা কোনও চিত্র গ্রন্থাগার বা ফাংশন ব্যবহার করতে পারবেন না।
  • আপনার প্রোগ্রামটি অবশ্যই 3 মিনিটের নিচে চলতে হবে এবং সমস্ত ইনপুট (স্যানিটি চেক) এর জন্য 10 এমবি এর অধীনে একটি ফাইল আউটপুট করতে হবে।
  • এটি , তাই বাইটের মধ্যে সংক্ষিপ্ততম কোডটি জিতবে!

আপনি বলছেন যে ফাইলটি সম্পূর্ণরূপে সঙ্কুচিত হতে পারে তবে তারপরে এটি অবশ্যই সমস্ত ইনপুটগুলির জন্য 30 কেবি এর নীচে হওয়া উচিত। একটি 999x999ফাইলের 30720 পিক্সেলের বেশি রয়েছে তাই এটি স্ব-বিরোধী বলে মনে হচ্ছে।
পিটার টেলর

@ পিটারটেলর এইচএম, কোনও কারণে আমি ভেবেছিলাম যে ৩০ কেবি যথেষ্ট পরিমাণের চেয়ে বেশি। জানি না আমি কী ভাবছিলাম ... সম্পাদিত। (এবং আমি কেবল বলেছি যে আপনি সংকোচনের ব্যবহার করতে পারেন বা নাও ব্যবহার করতে পারেন; আপনি যা চান তাই করুন।)
ডোরকনব

প্রস্থ: 4 বাইট উচ্চতা: 4 বাইট বিট গভীরতা: 1 বাইট রঙের ধরণ: 1 বাইট
সংক্ষেপণ

@ টেকনোসরাস ... হুম, কি?
ডুরকনব

1
আপনার উদাহরণটি সঠিক নয়: বিট গভীরতা: 8 (আরআরজিবিবিএএ)। বিটের গভীরতা 8 হ'ল (আরজিবিএ) নয় (আরআরজিবিবিএএ)।
গ্লেন রেন্ডার্স-পেহারসন

উত্তর:


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।

যুক্তিগুলি একটি লাইনে STDIN এর মাধ্যমে দেওয়া হয়, একটি স্পেস দ্বারা পৃথক করে, হেক্স মান (16 অক্ষর) হিসাবে রঙ এবং প্রস্থ / উচ্চতার জন্য পিক্সেলের সংখ্যা, যেমন:

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

yellow200.png

ফাইলের আকার 832 বাইট। একই রঙের সর্বাধিক আকারের চিত্র (n = 999) এর 6834 বাইট রয়েছে (10 এমবি নীচে)।

সমাধান দুটি গ্রন্থাগার ব্যবহার করে:

  • use Digest::CRC crc32; সিআরসি 32 মানগুলির শেষ অংশে।
  • 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ডিফল্ট দ্বারা ডিফল্ট ফাংশনটি রফতানি করে । ফাংশনটির জন্য আর্গুমেন্ট হিসাবে রেফারেন্সের প্রয়োজন হয় না এবং ফলাফলটি সরাসরি দেয় returns এটি পরিবর্তনশীল থেকে মুক্তি পেতে দেয় $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 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আরও কমপ্রেস করতে পারে না)।


দুর্দান্ত উত্তর (বরাবরের মতো), তবে গল্ফিং আরও এগিয়ে যেতে পারে - আমার কাছে 202, + 1 পাওয়া যায় -p। মাইকেলের উত্তরে অর্ন্তদৃষ্টি (ছাড়াও NA*Nএবং NNCVটেমপ্লেট), - String::CRC32ডিফল্টরূপে রপ্তানি y///c-4ঠিক আছে, হয় CH*টেমপ্লেট $iসর্বস্বান্ত করা, \cZ, barewords ঠিক আছ, -pএবং / /;prematch এবং postmatch মধ্যে স্থান আর্গুমেন্ট। আমি ভাবছি যদি আমি কিছু মিস করেছি এবং স্কোর 200 এর নিচে পেতে পারে তবে
ব্যবহারকারী 2846289

1
@ ভাদিমআর: দরকারী টিপস জন্য অনেক ধন্যবাদ। আমি ব্যবহার দ্বারা এমনকি এটি আরও গলফ পারা use Compress::Zlib;এবং 200. নিচের ≈ 10% পেয়েছিলাম
Heiko Oberdiek

5

পিএইচপি 214

আমি পিএইচপি-তে বিশেষজ্ঞ নই, গল্ফ করার জন্য জায়গা আছে। টিপস স্বাগত জানানো হয়।

<?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");

একটি পিএনজি ফাইল তৈরি করুন:

php png.php 20 FFFF00FF > output.png

বেস 64 স্ট্রিম উত্পন্ন করুন (আপনার ব্রাউজারের অ্যাড্রেস বারে ফলাফলটি পেস্ট করুন)

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

অবরুদ্ধ সংস্করণ:

<?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, তাই না? এবং, আমি উভয় গল্ফযুক্ত এবং আন-গল্ফ করা সংস্করণ থেকে কোনও সঠিক চিত্র পেতে পারি না, তবে আমার কোনও পিএইচপি অভিজ্ঞতা নেই, তাই যদি এটি অন্য সবার জন্য কাজ করে তবে এটি আমার পক্ষে ভুল করছে।
ব্যবহারকারী 2846289

1
@ ভাদিমআর, হ্যাঁ 214, আপনি ঠিক বলেছেন। আমি চেক করেছি, উত্পন্ন চিত্রটি আমার পক্ষে বৈধ।
মাইকেল এম।

আমার জন্য (আমি পিএইচপি 5.4.27.0 দিয়ে পরীক্ষা করি), চিত্রটি 4 বাইট সংক্ষিপ্ত - অ্যাডলার -32 ডিফল্ট ডেটাতে সংযুক্ত করা উচিত নয়? আইআই এবং ক্রোম চিত্রটি যেমন দেখায় খুশি, এফএফ হয় না। এই চিত্রটির সাথেও বিভিন্ন অ্যাপস আলাদাভাবে আচরণ করে।
ব্যবহারকারী 2846289

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")

এই স্ক্রিপ্টটি আরজিভি থেকে ইনপুট নেয়। কমান্ড লাইন থেকে এই স্ক্রিপ্টটি চালান, পছন্দ করুনpython 27086.py deadbeef 999

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.