Cubify Ini! Pelajaran dalam skala abu-abu ... eh ... warna ... eh ... terserah

27

Menjadi penggemar berat kubus Rubik dan seni keren, saya telah berupaya menggabungkan keduanya untuk melakukan beberapa hal yang sangat keren. Pada dasarnya memecahkan kubus Rubik miniatur untuk membentuk piksel yang belum sempurna dalam pembentukan seni kubus Rubik. Contoh seni semacam itu dapat dilihat melalui tautan ini: http://google.com/search?q=rubik%27s+cube+art

Sekarang, tujuan dari Code Golf ini adalah untuk membuat kode yang menerima gambar sebagai input, dan kemudian mengubahnya dengan cara berikut:

Gambar awalnya direduksi menjadi warna abu-abu web-safe. Alasan di balik ini adalah karena kita perlu mengisolasi palet grayscale web-safe (yaitu 000000, 333333, 666666, 999999, CCCCCC, dan FFFFFF). Algoritme pada metode kolorimetri konversi menjadi grayscale tersedia di: http://en.wikipedia.org/wiki/Grayscale#Colorimetric_.28luminance-preserving.29_conversion_to_grayscale , jika Anda ingin menggunakannya sebagai inspirasi.

Satu kemudian akan membuat skala abu-abu ke warna yang sesuai. Untuk memecahnya dengan cepat: 000000 akan merujuk ke biru Rubik, 333333 akan merujuk ke merah Rubik, 666666 akan merujuk ke hijau Rubik, 999999 akan merujuk ke oranye Rubik, merujuk ke kuning Rubik, dan FFFFFF akan merujuk ke putih Rubik.

Saya lebih suka bahwa kode yang Anda hasilkan dapat membuat dari palet foto langsung ke warna Rubik. Metode dua tahap dari konversi ke skala abu-abu web-aman dan kemudian ke palet Rubik yang sesuai hanya untuk memberi Anda ide tentang logika di balik proses, tetapi jika lebih mudah bagi Anda untuk melakukan ini, dengan segala cara melakukannya.

Nilai RGB sebenarnya untuk palet Rubik harus sesuai dengan yang berikut:

  • Merah: # C41E3A
  • Hijau: # 009E60
  • Biru: # 0051BA
  • Oranye: # FF5800
  • Kuning: # FFD500
  • Putih: #FFFFFF

Sebagai contoh, saya telah memangkas kepala Abraham Lincoln dari gambar berikut:, masukkan deskripsi gambar di sinidan memberikan algoritme untuk menghasilkan yang berikut:

masukkan deskripsi gambar di sini

Kotak ada di sana sehingga Anda dapat melihat bagaimana masing-masing miniatur Rubik's cube harus dikonfigurasi untuk membuat gambar. Ukuran sebenarnya dari gambar yang dihasilkan adalah 45 piksel kali 45 piksel, artinya (45/3) * (45/3) = 15 * 15 = 225 miniatur kubus Rubik akan digunakan untuk membuat gambar ini. Saya tidak mengharapkan Anda untuk menyajikan gambar yang dihasilkan dengan kisi seperti yang saya miliki.

Jadi ini yang dibutuhkan:

  1. Gambar yang akan diproses oleh algoritma ini harus berukuran x piksel lebar x piksel tinggi, sehingga x dan y adalah kelipatan dari 3. Ini untuk membantu dengan kemudahan rendering sebagai bagian dari mosaik kubus Rubik. Jika gambar Anda cukup besar, kurangi menjadi sekitar 45 x 45 hingga 75 x 75 atau sekitar dimensi sebelum pemrosesan disarankan. Ingatlah, komponen ukuran ini adalah OPTIONAL.

  2. Gambar perlu dikonversi ke palet kubus sextacolored Rubik untuk membuat mosaik.

  3. Gambar yang dihasilkan harus berupa file grafik yang valid setelah diproses. Untuk membuktikan bahwa kode Anda berfungsi, jalankan dengan citra salah satu presiden Amerika Serikat, atau selebritas Hollywood yang terkenal. Saya sudah menggunakan Abraham Lincoln dalam contoh saya, jadi presiden ini tidak bisa lagi digunakan. Pastikan Anda memberikan bahasa yang telah Anda gunakan, jumlah byte serta presiden / selebriti yang digunakan untuk menguji kode Anda, termasuk sebelum dan sesudah pemotretan ...

  4. Setiap entri harus memiliki presiden / selebriti yang unik sebagai ujian mereka. Saya tidak akan menerima duplikat. Ini akan memastikan bahwa hasil duplikat tidak digunakan untuk menguji entri kode yang berbeda. Sangat baik untuk mengatakan bahwa kode Anda berfungsi, itu hal lain untuk membuktikannya.

5. Kode terpendek menang.

Saya mengubah ini menjadi kontes popularitas ... Saya lebih suka melihat siapa yang bisa melakukan ini tanpa harus bersaing dalam jumlah byte ... Jadi saya akan menghadiahkan ini bersama dengan hadiah setelah 28 Februari 2014.

WallyWest
sumber
4
Saya pikir akan lebih baik jika Anda menambahkan nilai RGB Rubik ke posting daripada mengandalkan tautan.
SztupY
Apakah "gambar yang akan diproses harus berukuran lebar x piksel demi tinggi piksel" berarti bahwa pengubahan ukuran merupakan bagian dari kode atau gambar yang telah diproses sebelumnya ke ukuran yang diperlukan?
user2846289
Apakah ada keadaan mustahil dari Rubik's Cube jika Anda hanya membatasi satu wajah?
Nick T
1
@WallyWest Anda akan MENYUKAI aplikasi saya MineCam, ia melakukan ini, tetapi alih-alih membuat kotak, ia menggunakan blok kerajinan tambang, dan itu juga melakukannya 15 kali per detik dengan kamera iPhone waktu nyata, sehingga mengubah seluruh dunia di sekitar Anda menjadi sebuah ranjau alam semesta. itunes.apple.com/us/app/minecam/id675845303?mt=8 (Kalau saja itu juga bisa menghasilkan benih untuk dunia hahahaha tersebut)
Albert Renshaw
2
@WallyWest: ini bukan tentang malas. Masalahnya seharusnya memberi Anda semua informasi yang Anda butuhkan untuk memulai, bahkan jika internet lainnya mati. Dalam satu atau dua tahun, tautan itu mungkin diturunkan dan tidak seorang pun akan memperbarui tautan itu. Jika Anda memberikan informasi yang cukup tentang cara membuat warna abu-abu web-safe (yang tidak perlu untuk memecahkan masalah) Anda bisa saja dengan mudah menambahkan tabel pemetaan kecil, seperti #000000 => #0051BA, dll.
SztupY

Jawaban:

16

Imagemagick (108)

Versi: ImageMagick 6.8.7-7 Q16 x86_64 2013-11-27

Panggilan berikut:

$ convert -resize 75x75 -fx "q=p.intensity;q<1/6?#0051BA:q<2/6?#C41E3A:q<3/6?#009e60:q<4/6?#ff5800:q<5/6?#FFD500:#FFF" input output

di mana inputdan outputharus dimodifikasi untuk nama file input dan output.

Saya hanya menghitung karakter antara -resizedan #FFF", jika Anda pikir ini tidak valid, jangan ragu untuk berkomentar.

Saya menggunakan Lenna sebagai gambar (dia muncul di Playboy, dan siapa pun yang melakukan itu harus dianggap sebagai selebritas Hollywood, bukan?)

Memasukkan:

Masukkan gambar

Keluaran:

$ convert -resize 75x75 -fx "q=p.intensity;q<1/6?#0051BA:q<2/6?#C41E3A:q<3/6?#009e60:q<4/6?#ff5800:q<5/6?#FFD500:#FFF" Lenna.png LennaRubik.png

Gambar yang dihasilkan

Output diperbesar:

Gambar yang diperbesar

Catatan: menurut dokumen imagemagick Anda tidak dapat memiliki lebih dari satu operator kondisional dalam pernyataan, tetapi panggilan tersebut tampaknya masih berfungsi dengan baik, jadi mungkin ini sudah diperbaiki dan dokumen tidak diperbarui.

Running identify pada gambar hasil (untuk menunjukkan warna memang baik-baik saja):

$ identify -verbose LennaRubik.png
  (...)   
  Colors: 6
  Histogram:
       338: (  0, 81,186) #0051BA srgb(0,81,186)
      1652: (  0,158, 96) #009E60 srgb(0,158,96)
      1187: (196, 30, 58) #C41E3A srgb(196,30,58)
      1674: (255, 88,  0) #FF5800 srgb(255,88,0)
       706: (255,213,  0) #FFD500 srgb(255,213,0)
        68: (255,255,255) #FFFFFF white
  (...)

Jika Anda berpikir Lenna tidak dianggap sebagai selebritas yang pantas, inilah Bruce Willis:

Bruce Original

Bruce Small

Bruce Large

SztupY
sumber
+1 Saya pikir jawaban Anda hampir tidak ada duanya (atau bahkan tidak terkalahkan sama sekali). Saya hanya akan menyarankan agar Anda mengambil beberapa foto selebriti Hollywood atau presiden Amerika yang tidak perlu dipertanyakan dan menambahkan ini (tidak perlu menghapus Lenna, simpan keduanya). Kalau tidak, beberapa orang yang membosankan mungkin mengeluh dan downvote hanya karena itu.
Victor Stafusa
@ Viktor: Saya pikir Mathematica, Matlab atau Octave mungkin dengan mudah mengalahkan ini, karena kondisi di dalam fxbagian dapat dikompresi lebih jauh dalam bahasa yang memiliki ekspresifitas yang lebih baik. Dan bahasa-bahasa itu juga memiliki dukungan gambar asli (jadi tidak ada karakter yang hilang karena harus mengimpor imagemagick / gd / etc.)
SztupY
@SztupY Saya tahu tentang Lenna dengan sangat baik ... Saya akan menghitung itu ... Kerja bagus dengan Bruce Willis juga ...
WallyWest
1
Lenna lucu sekali. Naik.
blabla999
+1 untuk menggunakan alat yang tepat untuk pekerjaan itu. Menurut pemahaman saya, cara yang benar untuk menggunakan imagemagick adalah dengan memanggil gambar terlebih dahulu, daripada opsi, daripada file output.
CousinCocaine
14

Mathematica

Kami akan bekerja dengan wilayah persegi dari perangko AS yang menampilkan Greta Garbo. Ini akan disebut sebagai j.

j

f[i_,rs_,m_:True]:=
Module[{(*rs=rastersize-4*)r={0.77,0.12,0.23},gr={0,0.62,0.38},b={0,0.32,0.73},o={1,0.35,0},y={1,0.84,0},w={1,1,1},
c1={r,gr,b,o,y,w},grayGreta,garboColors},
grayGreta=(*Reverse@*)ImageData[ColorQuantize[Rasterize[i,(*ImageResolution \[Rule]15*)RasterSize->rs+1,ImageSize->rs],6]];
garboColors=Union@Flatten[grayGreta,1];
ArrayPlot[grayGreta/.Thread[garboColors-> RGBColor@@@c1],
Mesh->If[m==True,{rs-1,rs-1},None],MeshStyle->Black]]

Fungsi f mengambil 3 parameter:

  • i yang mengacu pada gambar
  • rs, ukuran raster
  • m, variabel boolean yang menyatakan apakah garis Mesh harus digunakan. (Pengaturan standar adalah Benar).

Menggunakan ukuran raster 15, 30, 45, dan 75:

GraphicsGrid[{{f[j, 15], f[j, 30]}, {f[j, 45], f[j, 75]}}, ImageSize -> 800]

4 garbos

Saya tidak bisa membayangkan ada orang yang membuat kubus Rubrik dengan begitu banyak potongan! Meskipun demikian, latihan yang menarik.


Bermain-main dengan warna

Ini dari entri sebelumnya. Kode ini sedikit berbeda. Graphicsdigunakan sebagai ganti ArrayPlot. Kami juga menggunakan stempel lengkap meskipun tidak persegi.

Ada 6! = 720 permutasi dari warna kubus Rubrik.

Berikut ini menampilkan gambar tengah dari baris atas (atur 6 gambar di bawah). Ketika nilai skala abu-abu disusun dari yang paling gelap ke paling terang, warnanya adalah {r, gr, b, o, y, w}. Variasi lain tetap bekerja.

i adalah gambar asli dalam skala abu-abu.

Graphics[Raster[(g=Reverse@ImageData[ColorQuantize[Rasterize[i,RasterSize->75],6]])
/.Thread[Union@Flatten[g,1]-> {{7,1,2},{0,6,4},{0,3,7},{10,4,0},{10,8,0},{10,10,10}}/10]]]

i adalah gambar grayscale asli dari cap Greta Garbo lengkap.

Rasterize[garbo,RasterSize->75 meraster gambar menjadi array 75 dengan 75.

ColorQuantize[<>, 6] mengurangi nilai skala abu-abu ke set 6.

ImageDatamengambil larik data dari gambar; itu terbalik.

Reverse membalik array data, maka gambar, sisi kanan atas.

garboColors adalah 6 nilai skala abu-abu dalam gambar terkuantisasi.

Graphics[Raster menampilkan gambar akhir.

rubrikColors adalah nilai RGB dari 6 warna Rubrik cube.

Berbagai permutasi warna Merah, Hijau, Biru, Oranye, Kuning, dan Putih diberikan.

r={0.77,0.12,0.23};gr={0,0.62,0.38};b={0,0.32,0.73};o={1,0.35,0};y={1,0.84,0};w={1,1,1};
c1={r,gr,b,o,y,w};
c2={r,b,gr,o,y,w};
c3={b,r,gr,o,y,w};
c4={gr,b,r,o,y,w};
c5={b,r,gr,y,o,w};

Dan kodenya:

grayGreta=Reverse@ImageData[ColorQuantize[Rasterize[i,RasterSize->75],6]];
garboColors=Union@Flatten[grayGreta,1];
Grid[{{i,
Graphics[Raster[grayGreta/.Thread[garboColors-> c1]]],
Graphics[Raster[grayGreta/.Thread[garboColors-> c2]]]},
{Graphics[Raster[grayGreta/.Thread[garboColors-> c3]]],
Graphics[Raster[grayGreta/.Thread[garboColors-> c4]]],
Graphics[Raster[grayGreta/.Thread[garboColors-> c5]]]}}]

garbos


Garbos Galore

Berikut adalah 72 (dari 720) gambar Greta Garbo yang menggunakan 6 warna Rubrik cube. Beberapa gambar bekerja lebih baik daripada yang lain, bukan begitu?

GraphicsGrid@Partition[(Graphics[Raster[grayGreta /. Thread[garboColors -> #]]] & 
/@ Take[Permutations[{r, gr, b, o, y, w}, {6}], 72]), 12]

garbos berlimpah

DavidC
sumber
Greta, oh Greta ... Ini ternyata lebih baik dari yang aku duga. @ Davidvidarrarr, kerja bagus di sini ...
WallyWest
@WallyWest. Terima kasih. Itu adalah tantangan yang sangat menarik.
DavidC
Saya sangat yakin Mathematica akan mengalahkan imagemagick, tidak bisakah ini bermain golf lebih jauh? Apakah semua fungsi itu diperlukan?
SztupY
1
@SztupY Setengah kode ini didedikasikan untuk mendapatkan warna yang benar. Reversebisa dihilangkan, membiarkan gambarnya terbalik, tapi saya tidak melihat peluang lain. Mathematica ekspresif tetapi menggunakan kata-kata besar. Seseorang yang mahir dalam gambar mungkin bisa mengurangi ukuran kode sedikit tapi saya ragu mereka bisa mengalahkan kode imagemagick Anda.
DavidC
1
Memang ada beberapa inkonsistensi di seluruh kode. Saya harap mereka sekarang pergi. itahan gambar aslinya. grsingkatan dari Rubrik's green. gmengacu pada data gambar raster dan terkuantisasi untuk gambar skala abu-abu.
DavidC
6

Smalltalk (Smalltalk / X), 289 139 *

masukan: i; output: r

r:=i magnifiedTo:75@75.
r colorMapProcessing:[:c||b|b:=c brightness.Color rgbValue:(#(16r0051BA 16rC41E3A 16r009e60 16rff5800 16rFFD500 16rFFFFFF)at:(b*6)ceiling)]

memasukkan:

masukkan deskripsi gambar di sini

keluaran:

masukkan deskripsi gambar di sini

diperbesar:

masukkan deskripsi gambar di sini

(untuk semua anak muda: ini BUKAN Madonna ;-)

[*] Saya belum menghitung perbesaran hingga 75x75 (baris pertama) - bisa menggunakan yang sudah diubah ukurannya sebagai input. Semoga tidak apa-apa dengan Anda.

blabla999
sumber
Saya mengagumi Marilyn Monroe ... Pilihan bagus ... Mengubah ukuran adalah fitur opsional ...
WallyWest
4

Catatan tambahan, dan warna Rubik yang BENAR! ;-)

Nah, solusi ini sedikit di luar topik di sini, karena terbatas pada bidang yang sangat khusus. Tetapi setelah banyak frustrasi dengan misalnya "pertanyaan nomor aneh" (karena tidak dapat menghasilkan sesuatu yang praktis bekerja) saya memutuskan untuk menerbitkan sesuatu dan dengan demikian mengeluarkan ini dari tumpukan coretan setengah jadi saya dan membuatnya layak.

Solusinya mengeksploitasi fakta, bahwa revisi pertama dari pertanyaan ini mendefinisikan warna yang dibutuhkan berdasarkan tautan ke situs, yang dengan jelas menyatakan, bahwa warna Pantone (R) harus digunakan, dan warna RGB hanya merupakan perkiraan. Kemudian saya berpikir, mengapa saya harus melakukan perkiraan, ketika saya bisa membuat warna asli? - :)

10 dict begin
/Size 75 def
/Names  [(PMS 012C) (PMS 021C) (PMS 347C)   (PMS 200C)    (PMS 293C)   ] def
/Colors [[0 .16 1 0][0 .65 1 0][1 0 .39 .38][0 .9 .72 .28][1 .56 0 .27]] def
<</PageSize [Size dup]>> setpagedevice
Size dup scale
true setoverprint
(%stdin) (r) file 100 string readline pop 
(r) file <</CloseSource true>>/DCTDecode filter
0 1000000 string 
dup <</CloseTarget true>>/NullEncode filter 
{
    3 index 3 string readstring
    {
        4 -1 roll 1 add 4 1 roll
        {} forall
        0.11 mul exch 0.59 mul add exch 0.3 mul add cvi
        1 index exch write
    } {pop exit} ifelse
} loop
closefile
0 3 -1 roll getinterval
exch closefile
/data exch def
/n data length sqrt cvi def
1 1 Names length {
    /N exch def
    { 
        dup N Names length 1 add div gt 
            {N 1 add Names length 1 add div gt 
                {1} {0} ifelse} 
            {pop 1} 
        ifelse
    } settransfer
    [/Separation Names N 1 sub get /DeviceCMYK {
        Colors N 1 sub get 
        { 1 index mul exch } forall pop
    }] setcolorspace
    <<
        /ImageType        1
        /Width            n
        /Height           n
        /ImageMatrix      [n 0 0 n neg 0 n]
        /BitsPerComponent 8
        /Decode           [0 1]
        /DataSource       data
    >> image
} for
showpage
end

Kode ini harus disimpan sebagai misalnya rubik.psdan kemudian diumpankan ke Ghostscript dengan mantra biasa:

gs -q -sDEVICE=psdcmyk -o out.psd rubik.ps

Itu kemudian menunggu Anda di baris berikutnya, untuk input nama file JPG misalnya

kelly.jpg

dan, jika semuanya berjalan dengan baik, simpan output ke out.psdfile.

Input harus persegi RGB JPEG (ukuran apa pun), output PSD dengan saluran warna spot. Anda perlu Photoshop untuk melihat file. Mengubah perangkat GS dari yang psdcmyklainnya tidak akan menghasilkan apa-apa yang dapat digunakan. JPEG sebagai input - karena juru bahasa postscript dapat mendekodekan aliran data dari itu secara langsung. Bentuk kotak - karena program bergantung pada sqrtpanjang tali untuk menemukan lebar (dan tinggi) gambar.

Baris pertama menentukan ukuran gambar output (dapat diubah dari default 75) dan palet warna (warna dan jumlahnya juga dapat diubah). Ada lagi yang bukan kode-keras, saya pikir.

Apa yang sedang terjadi? Stream triplet RGB dikonversi dengan cepat ke string nilai grayscale (dengan rumus sederhana), kamus gambar contone 8-bit yang biasa dibuat dan digunakan untuk melukis 5 gambar identik di atas satu sama lain dalam 5 Separationruang warna. Caranya adalah dengan menerapkan fungsi transfer sebelum setiap doa dari imageoperator. Misalnya untuk cat kuning fungsi ini mengembalikan 0 untuk nilai input dalam 0,167 .. hanya kisaran 0,333, dan 1 sebaliknya.

Memasukkan:

masukkan deskripsi gambar di sini

Cuplikan layar keluaran 75x75 terbuka di Photoshop, diperbesar 800%:

masukkan deskripsi gambar di sini

Dan palet saluran Photoshop:

masukkan deskripsi gambar di sini

pengguna2846289
sumber
1
+1 untuk menggunakan Grace Kelly ... Anda benar-benar menghargai saya ...
WallyWest
3

C #

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        unchecked
        {
            var t = new[] { 0xFFC41E3A, 0xFF009E60, 0xFF0051BA, 0xFFFF5800, 0xFFFFD500, 0xFFFFFFFF }.Select(v => Color.FromArgb((int)v)).ToArray();
            var o = new Bitmap(Bitmap.FromFile(args[1]));
            var m = double.Parse(args[0]);
            var r = Math.Min(m / o.Width, m / o.Height);
            var w = (int)(o.Width * r);
            var h = (int)(o.Height * r);

            o = new Bitmap(o, w - (w % 3), h - (h % 3));
            for (int y = 0; y < o.Height; y++)
                for (int x = 0; x < o.Width; x++)
                    o.SetPixel(x, y, N(o.GetPixel(x, y), t));
            o.Save(args[2], ImageFormat.Png);
        }
    }

    static Color N(Color c, Color[] t)
    {
        return t.OrderBy(v => Math.Abs(W(v) - W(c))).First();
    }

    static double W(Color c)
    {
        return .11 * c.B + .59 * c.G + .30 * c.R;
    }
}

Anda perlu menjalankannya dengan 3 parameter:

foo.exe 75 d:\test.jpg d:\out.png

Di mana 75maks. lebar / tinggi, d:\test.jpgadalah file input dan d:\out.pngfile output.

Output untuk berbagai gambar dalam kontes ini:

WallyWest SztupY 1 SztupY 2 blabla999

Selebriti saya sendiri:

Halaman dalam!

Keluaran:

Garth 75 Garth 225

Namun, ukuran lain (lebih besar dari 75x75) memang menghasilkan gambar yang lebih baik:

150 300

Dan, jika kita tetap dengan presiden:

DubbaYa 294 DubbaYa 75 DubbaYa 225

Karena ini bukan codegolf (lagi?) Saya tidak repot-repot untuk "meminimalkan" kode terlalu banyak. Juga, karena instruksi tidak secara spesifik menyebutkan gambar harus sama lebar dengan tinggi (kotak) saya tidak repot-repot memotong; Saya lakukan , namun, pastikan gambar merupakan kelipatan dari lebar 3 pixel / tinggi. Jika Anda ingin gambar persegi, gunakan input persegi : PAkhirnya; Algoritma itu jauh dari optimal.

Beberapa lagi (karena orang-orang menyukai pahlawan panas / pahlawan internet lebih banyak : P)

Kari Byron 300 Kari Byron 75 Kari Byron 225 Hoff 300 The Hoff 75 The Hoff 225

RobIII
sumber
3

Brainfuck

++++[->+[,.----------]<]>>>>---->->++++++++++>>------------>+++>+++>--
--->++++++[->+++++<]---->+[-<+++++++<+++<+++++<+++<+++<++++++<++++++<+
<++>>>>>>>>>]<[<]<<,+[,<++++++>[>++++++[->+++++++<]>+[<<[->]>[<]>-]<<<
->]+<[-[-[-[-[[-].>>>>>>>>.<.<<<<<<-<]>[->>>>>[.<]<<]<]>[-.>>>[>]<<<.<
.[<]<<]<]>[--.+>>>[>]<<.[<].<<]<]>[--.+>>>[>]<.[<].<<]<]>[--...+],,+]

Ini membutuhkan juru bahasa BF / kompiler yang memiliki -1 sebagai EOF dan yang memiliki lebih tinggi dari sel 8 bit JIKA salah satu piksel merah adalah 255. Atau kalau tidak akan berhenti prematur karena tidak akan dapat membedakan antara EOF dan nilai 0xFF . Dengan jitbf Anda memiliki apapun yang dimiliki mesin sebagai ukuran integer dan dapat melakukan ini untuk memaksa -1 sebagai EOF:

jitbf --eof -1 rubiks.bf < angelina.pnm > angelina-rubix.pnm

Format file gambar yang diberikan adalah file PNM RGB penuh (P6), mentah sebagai opsi di Gimp.

Ini menggunakan saluran hijau saja (yang merupakan salah satu dari banyak cara untuk mengubah gambar warna ke skala abu-abu). Ini mengurangi nilai sebesar 43 tanpa mengurangi nilai di bawah nol untuk mencari tahu warna rubiks mana yang akan digunakan dan memiliki sakelar yang mencetak warna RBG yang tepat yang sesuai.

Gambar Angelina Jolie dari Hackers (1995) diperkecil menjadi 75x75 dan diproses dengan aplikasi:

Angelina Jolie 75x75 / Penggunaan Wajar Angelina Jolie 75x75 dalam warna kubus Rubiks / Penggunaan Wajar Skala 6x yang sama

Sama, hanya saya yang menggunakan ukuran aslinya :

Hanya saja tidak diperkecil dulu / Penggunaan wajar

Dan karena saya peramal inilah presiden juga:

Arnold Schwarzenegger CC dari Wikipedia

Sylwester
sumber
Di luar topik, tetapi todays xkcd juga memiliki referensi untuk Peretas (1995)
Sylwester
1
Yang ini juga tidak: xkcd.com/1247
Shade
1

Objektif-C

Saya melihat tantangan ini tadi malam dan memiliki waktu yang sedikit membingungkan dengan -[NSArray indexOfObject:inSortedRange:options:usingComparator:], karenanya penundaan.

- (UIImage  *)rubiksImage:(UIImage *)inputImg
{
    //Thank you http://stackoverflow.com/a/11687434/1153630 for the greyscale code
    CGRect imageRect = CGRectMake(0, 0, inputImg.size.width, inputImg.size.height);

    int width = imageRect.size.width;
    int height = imageRect.size.height;

    uint32_t *pixels = (uint32_t*)malloc(width * height * sizeof(uint32_t));

    memset(pixels, 0, width * height * sizeof(uint32_t));

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

    CGContextDrawImage(context, imageRect, [inputImg CGImage]);

    const int RED = 1;
    const int GREEN = 2;
    const int BLUE = 3;

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            uint8_t* rgbaPixel = (uint8_t*)&pixels[y * width + x];
            uint32_t grayPixel = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];

            NSArray *r = [self rubixColorFromGrey:grayPixel];

            rgbaPixel[RED] = [r[2] integerValue];
            rgbaPixel[GREEN] = [r[1] integerValue];
            rgbaPixel[BLUE] = [r[0] integerValue];
        }
    }

    CGImageRef newCGImage = CGBitmapContextCreateImage(context);

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);

    UIImage* newUIImage = [UIImage imageWithCGImage:newCGImage];

    CGImageRelease(newCGImage);

    return newUIImage;
}

- (NSArray *)rubixColorFromGrey:(uint32_t)p
{
    NSArray *colors = @[@0, @51, @102, @153, @204, @255];

    NSUInteger index = [colors indexOfObject:@(p)
                               inSortedRange:NSMakeRange(0, colors.count)
                                     options:NSBinarySearchingInsertionIndex | NSBinarySearchingFirstEqual
                             usingComparator:^(id a, id b) {
                                return [a compare:b];
                             }];
    switch (index) {
        case 0:
            return rgb(0, 81, 186);
            break;
        case 1:
            return rgb(196, 30, 58);
            break;
        case 2:
            return rgb(0, 156, 96);
            break;
        case 3:
            return rgb(255, 82, 0);
            break;
        case 4:
            return rgb(255, 213, 0);
            break;
        case 5:
            return rgb(255, 255, 255);
            break;

        default:
            break;
    }

    return colors; //go wild
}

NSArray *rgb(int r, int g, int b)
{
    return @[@(r), @(g), @(b)];
}

Saya menjalankannya di iPad saya seperti ini:

UIImageView *img = [[UIImageView alloc] initWithImage:[self rubiksImage:[UIImage imageNamed:@"danny.png"]]];
[img setCenter:self.view.center];
[self.view addSubview:img];

Sebelum Danny DeVito Sebelumnya Setelah Danny DeVito After

Sebelum Grace Kelly Sebelumnya Setelah Grace Kelly After

Max Chuquimia
sumber
1

Python

Format: python rubik.py <input> <max_cubes> <output>.

Coverts pixel to grayscale menggunakan algoritma yang disarankan.

import Image, sys

def rubik(x, max_cubes = 25):

    img = x
    max_cubes *= 3

    if x.size[0] > max_cubes or x.size[1] > max_cubes:

        print "Resizing image...",

        if x.size[0] > x.size[1]:
            img = x.resize((max_cubes, int(max_cubes * float(x.size[1]) / x.size[0])), Image.ANTIALIAS)
        else:
            img = x.resize((int((max_cubes * float(x.size[0]) / x.size[1])), max_cubes), Image.ANTIALIAS)

    if x.size[0] % 3 or x.size[1] % 3:
        print "Sizes aren't multiples of 3"
        return

    print "Image resized to %i x %i pixels" % img.size

    out = Image.new('RGB', img.size)

    print "Converting image...",

    for x in xrange(out.size[0]):
        for y in xrange(out.size[1]):
            r, g, b = img.getpixel((x, y))
            if r == g == b == 255:
                out.putpixel((x,y), (255, 255, 255))
            else:
                l = 0.2126 * r + 0.7152 * g + 0.0722 * b
                l /= 255
                out.putpixel((x,y), (
                        (0x00, 0x51, 0xBA),
                        (0xC4, 0x1E, 0x3A),
                        (0x00, 0x9E, 0x60),
                        (0xFF, 0x58, 0x00),
                        (0xFF, 0xD5, 0x00)
                    )[int(5 * (l <= 0.0031308 and 12.92 * l  or 1.055 * l ** (1/2.4) - 0.055))])

    print "Image converted successfully."

    print "Stats:"
    h, v = img.size[0] / 3, img.size[1] / 3
    print "   ", h, "horiz. Rubik cubes"
    print "   ", v, "vert. Rubik cubes"
    print "   ", h * v, "total Rubik cubes"

    return out.resize((out.size[0], out.size[1]))

if __name__ == "__main__":
    rubik(Image.open(sys.argv[1]).convert("RGB"), int(sys.argv[2])).save(sys.argv[3])

Memasukkan:

Sandro Pertini
(sumber: ilmamilio.it )

Output dengan max_cubes = 25:

Sandro Pertini, Rubik'd 1

Output dengan max_cubes = 75:

Sandro Pertini, Rubik'd 2

Output dengan max_cubes = 225:

Sandro Pertini, Rubik'd 3

Oberon
sumber
Bukankah warna putih hilang? Dan yang paling gelap harus biru, tetapi, seperti yang saya lihat sekarang, itu masalah dengan beberapa gambar lain juga.
user2846289
@VAdimiR Whoops! Memetakan mereka dalam urutan yang salah. Sedangkan untuk putih tidak muncul, itu karena presisi FP (1,055 - 0,055 = 0,9999999999999999). Saya pikir saya harus hardcode putih, yang tidak sulit, karena itu akan muncul hanya pada nilai asli #FFFFFF.
Oberon
Tentang putih, pendapat saya adalah kisaran 0..1 (terang) dibagi menjadi 6 bagian, dan apa pun 0.83..1.00 dipetakan menjadi putih, atau jika tidak, tidak akan ada gunanya membuat gambar 6 warna kubus , tapi begitulah cara saya membacanya.
user2846289
@Oberon Pilihan menarik menggunakan Pertini ... Dia hampir hidup sampai usia 94 ... Dan pekerjaan hebat menggunakan Python, dan harus saya akui, bukan salah satu bahasa termudah yang pernah saya jumpai, yang dilakukan dengan sangat baik!
WallyWest