ASCII metninden PBM bitmap dosyaları oluşturma


19

PBM (Taşınabilir BitMap) formatında çok basit bir ASCII siyah-beyaz bitmap biçimidir.

'J' harfi için bir örnek (wikipedia bağlantısından kopyalanmış):

P1
# Bu, "J" harfinin örnek bir bit eşlemidir
6 10
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
1 0 0 0 1 0
0 1 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Bu şık küçük formatta dosyalar oluşturmak için küçük bir araç oluşturma zamanı!

Sizin Amacınız aşağıdaki kurallara (herhangi bir dilde) o uyan, en kısa programı yazmaktır:

  1. Programınız stdin'den bir dize alır (örneğin CODEGOLF.STACKEXCHANGE.COM!)
  2. Dizenin bitmapped (okunabilir) temsili bir PBM dosyası oluşturur.
  3. Her karakter 8x8 ızgara olarak oluşturulur.
  4. [AZ] (tümü büyük harf), boşluk, nokta ('.') Ve ünlem işareti ('!') Karakterlerini desteklemelisiniz.
  5. Harici kütüphanelere izin verilmez (kesinlikle PBM ile ilgili kütüphaneler yoktur)!
  6. Kullanılan karakter seti sadece programınızın dışında olmamalıdır. Zorluğun bir kısmı karakterleri verimli bir şekilde saklamak ...

PBM formatının geçerliliğinin test edilmesi GIMP (veya diğerleri) ile yapılabilir. Örnek giriş ve çıkışını gösterin!

En kısa çözüm 2012-01-31'de cevap puanları ile ödüllendirilecektir.

İyi eğlenceler golf!

Not: (umarım) daha fazla rakip çekmek için bir lütuf (benim kodgolf itibarımın büyük bir kısmı yüzde olarak) ekledim.


"Bit eşlemli gösterimi" ile, harflere benzeyen bir şeye yakın olan bir karakter temsilini mi kastediyorsunuz? Ne kadar yakın? İkili kod veya braille veya mors kodunun bitmap temsiline izin vermek ister misiniz?
Howard

@Howard: fikir 'render' (bitmapped) ama yine de insan tarafından okunabilir formda ( lettersbaşka bir deyişle) orijinal giriş metnini içeren bir pbm görüntüsü oluşturmaktır . Bağlantılı örnek aksine değil.
ChristopheD

Kolmogorov-complexity etiketini ekledim çünkü programın büyük kısmı 30 bitmap olacak.
Peter Taylor

@Peter Taylor: Güzel nokta, teşekkürler!
ChristopheD

"Harici kütüphane" yi neyin oluşturduğuna dair uzun ve acılı bir tartışma yapacağımızı hissediyorum.
JB

Yanıtlar:


9

GolfScript, 133 bayt

Bu dayanmaktadır 164 baytlık Perl çözümüme ve aynı kırıntılarla dolu 4 x 5 piksel yazı tipini kullanıyor. Yine, önce okunabilir sürümü vereceğim:

{91,65>"!. "+?}%:s"P4"\,8*8'FONT DATA HERE'{16base}%[3]/{:p;{[p=0]0=}s%}%]n*

Burada, FONT DATA HERE71 bayt ikili paketlenmiş yazı tipi verisi anlamına gelir. Kodlama Perl sürümünden biraz farklıdır: paketlenmiş dizeyi boşlukta bölmek yerine, önce onu genişletirim ve sonra kemere bölerim 3(sadece yazı tipinin herhangi bir yerinde oluşmaması nedeniyle seçilir).

Gerçek komut dosyasındaki yazı tipi verileri yazdırılamayan karakterler içerdiğinden, aşağıdaki altıgen dökümü olarak veriyorum. kullanımxxd -rOnaltılık dökümü tekrar yürütülebilir GolfScript koduna dönüştürmek için :

0000000: 7b39 312c 3635 3e22 212e 2022 2b3f 7d25  {91,65>"!. "+?}%
0000010: 3a73 2250 3422 5c2c 382a 3827 36e6 eff6  :s"P4"\,8*8'6...
0000020: 9219 8996 e6e7 7959 95f4 3999 9888 921a  ......yY..9.....
0000030: 8fd9 9998 2959 9514 3fe8 9eeb f21c 89b9  ....)Y..?.......
0000040: e9e6 2959 6564 3999 9889 929a 8999 8ba1  ..)Yed9.........
0000050: 295f 9283 9e6e f869 269f 9968 79e2 6299  )_...n.i&..hy.b.
0000060: 2f48 3327 7b31 3662 6173 657d 255b 335d  /H3'{16base}%[3]
0000070: 2f7b 3a70 3b7b 5b70 3d30 5d30 3d7d 7325  /{:p;{[p=0]0=}s%
0000080: 7d25 5d6e 2a                             }%]n*

Perl betiğinin aksine, bu kod setin dışındaki karakterleri yazdırır A- Z,! , ., spacekomik görünüşlü küçük squiggles olarak. Dalgalı kenarları boşluklarla değiştirmek 2 ekstra karaktere mal olur; Onları tamamen kaldırmanın maliyeti 4.

Bu benim ilk GolfScript programım, bu yüzden optimizasyon için yer varsa şaşırmam. Şöyle çalışır:

  • {91,65>"!. "+?}%:s(geçerli girdi karakterleri eşler A- Z, !, .,space 28 ve devir sonucu - sayılar 0) s. Geçerli kümenin dışındaki tüm karakterler -1 olarak eşlenir, bu da yazdırıldığında dalgalı çizgiler oluşturur.

  • "P4"\,8*8"P4" değerlerini, girişin uzunluğunun 8 katı ve 8'i istifin üzerine iter. Sonunda yazdırıldığında, bunlar PBM başlığını oluşturur.

  • {16base}%[3]/önceki yazı tipi verisi dizesini alır, her baytını iki nibble'a böler ve sonucu değerle ayrılmış bloklara böler 3. {:p;{[p=0]0=}s%}%daha sonra bu blokların üzerinden geçer, önce her bloğu değişkene patar ve ardından yeniden eşlenen giriş dizesi üzerinde döngü yapar s, her karakteri karşılık gelen ofsetteki değerle değiştirir p. Komik görünümlü yapı , sonunu geçmiş herhangi bir ofset için 0 döndürmesi dışında [p=0]0=aynı şeyi yaparp=p ; Gerçekten hoşuma gitmedi, ancak bununla başa çıkmak için daha kısa bir yol bulamadım.

  • Son olarak, ]n*yığındaki her şeyi (üç başlık değeri ve görüntü veri dizisi) alır ve bunları yazdırma için yeni satırlarla birleştirir.


Ciddi derecede kısa (herhangi bir metrik ile). Güzel!
ChristopheD

12

Perl, 164 bayt, zlib / gzip sıkıştırması yok

Sorun üzerinde uyuduktan sonra, ilk çözümümden çok daha kısa bir çözüm bulmayı başardım. Hüner, kurallarda küçük bir boşluktan yararlanmaktır: karakterlerin her biri 8 x 8 piksel sığması gerekir, ancak hiçbir şey doldurmaları gerektiğini söylemez tüm bu alanı . Bu yüzden kendi 4 x 5 piksel yazı tipimi çizdim ve iki karakteri 5 bayta toplamamı sağladım.

Çıktı şöyle görünür:

"SELAM DÜNYA!" (ölçeklendirilmiş x 4)

    "OH! HIZLI KAHVERENGİ FOX ZARARLI KÖPEK ÜZERİNDE ATLAR." (orijinal boyut)

Gömülü font verileriyle gerçek kodu vermeden önce, izinsiz bir sürümü göstereyim:

y/A-Z!./\0-\033/ for @a = <> =~ /./g;
say "P4 " . 8*@a . " 8";
for $p (qw'PACKED FONT DATA') {
    print chr vec $p, ord, 4 for @a;
}

Gerçek kodda, PACKED FONT DATAsekiz boşlukla sınırlandırılmış satırdan (ikili 14 baytlık satır ve bir 13 baytlık bir artı boş satırlar için üç tek boş bayt) oluşan bir ikili dize ile değiştirilir. Yazı tipimi, paketlenmiş verilerin boşluk, tek tırnak veya ters eğik çizgi içermeyeceği şekilde, kodlanmış olabilmesi için tasarladım qw'...'.

Paketlenmiş font dizesi yazdırılamayan karakterler içerdiğinden, gerçek komut dosyasını onaltılık döküm olarak sağladım. xxd -rTekrar çalıştırılabilir Perl koduna dönüştürmek için kullanın :

0000000: 792f 412d 5a21 2e2f 002d 1b2f 666f 7240  y/A-Z!./.-./for@
0000010: 613d 3c3e 3d7e 2f2e 2f67 3b73 6179 2250  a=<>=~/./g;say"P
0000020: 3420 222e 382a 4061 2e22 2038 223b 666f  4 ".8*@a." 8";fo
0000030: 7224 7028 7177 2700 20e6 e6ff 9612 8999  r$p(qw'. .......
0000040: e6e6 7759 99f5 0420 9999 8898 128a df99  ..wY... ........
0000050: 9928 5999 1504 20ef 98ee fb12 8cb9 e9e9  .(Y... .........
0000060: 2659 6965 0420 9999 8899 928a 9989 ab21  &Yie. .........!
0000070: 599f 8220 e9e6 8f96 62f9 9986 972e 2699  Y.. ....b.....&.
0000080: f284 2000 2000 2729 7b70 7269 6e74 2063  .. . .'){print c
0000090: 6872 2076 6563 2470 2c6f 7264 2c34 666f  hr vec$p,ord,4fo
00000a0: 7240 617d                                r@a}

Şöyle çalışır:

  • (De-golfed versiyonda) ilk satır, giriş tek bir satır okur (uygun olarak bir arka yeni satır çıkarılır) karakter dizisi böler ve harfler haritalar Aiçin Zve karakterleri !ve ., karakter kodlarının 0-28 hangi normalde ASCII / Unicode'daki yazdırılamaz kontrol karakterlerine karşılık gelir. (Bunun küçük bir yan etkisi, girişteki tüm sekmelerin Js olarak yazdırılmasıdır .) Çıkış döngüsü 28'in üzerindeki kodları yine de boşluklara dönüştürdüğü için boşluk karakteri eşlenmeden bırakılır.

  • İkinci satır sadece PBM başlığını yazdırır. Perl 5.10 sayözelliğini kullanır , bu yüzden çalışması için bu komut dosyasını çalıştırmanız gerekir perl -M5.010.

  • Çıktı döngüsü, boşlukla sınırlandırılmış paketlenmiş görüntü satırlarının listesini alır ve her birini $psırayla atar . (Yazı tipini, paketlenmiş verilerin boşluk veya 'karakter içermeyeceği şekilde tasarladım .) Ardından @a, Perl veckomutunu kullanarak , eşlenen karakter koduna karşılık gelen 4 bitlik görüntüyü görüntü satırından ayıklamak için, 8 bitlik bir bayta yerleştirir ve yazdırır.


Eski cevap, 268 bayt:

Bu hızlı ve kirli bir ilk denemedir. PleaseStand'ın yazı tipini çaldım ve kaynak kodumla birlikte sıkıştırdım. Ortaya çıkan komut dosyası çoğunlukla yazdırılamaz olduğundan, burada bir hexdump; xxd -ryürütülebilir Perl koduna dönüştürmek için kullanın :

0000000: 7573 6520 436f 6d70 7265 7373 275a 6c69  use Compress'Zli
0000010: 623b 6576 616c 2075 6e63 6f6d 7072 6573  b;eval uncompres
0000020: 7320 2778 da85 d03d 4b03 4118 85d1 452c  s 'x...=K.A...E,
0000030: b69c 72cb 7519 4894 552c 2c02 3319 ee5c  ..r.u.H.U,,.3..\
0000040: d7b8 5a89 6093 4634 7e82 c490 6c91 8597  ..Z.`.F4~...l...
0000050: 80fe 7267 d660 23ae e52d 0e0f dcd6 f8c3  ..rg.`#..-......
0000060: e9d1 5e6e ccec a15c ddb5 c5d5 495e 94a3  ..^n...\....I^..
0000070: 83b7 c7f9 73f3 5216 f9a8 787a 5fea 666c  ....s.R...xz_.fl
0000080: 9dd1 b763 dd98 76f8 2df6 0799 5811 7144  ...c..v.-...X.qD
0000090: 4acc ee9d b8b0 c90f 7e4a 8264 6016 cbd7  J.......~J.d`...
00000a0: 79f3 1b91 047c 4055 409e 9e54 1dda ed41  y....|@U@..T...A
00000b0: 9a20 8080 6adc 5c47 8488 7495 f621 01d7  . ..j.\G..t..!..
00000c0: 6b6c 902e b6c8 2a6a 6643 f56f e99c 115d  kl....*jfC.o...]
00000d0: 5c7a f1b2 13d0 3453 790f da74 c813 751d  \z....4Sy..t..u.
00000e0: 11ce d821 ad90 247f 2292 5b54 c14f 3c4e  ...!..$.".[T.O<N
00000f0: 49c5 4c53 a1a7 c478 391c 714c f113 0747  I.LS...x9.qL...G
0000100: ab6c 4482 9fd2 177a 5677 6327            .lD....zVwc'

Açılmış Perl kodu aşağıdaki giriş bölümünden oluşur:

y;A-Z.! ;;cd,say"P4 ",8*length," 8"for$t=<>

ardından aşağıdaki kodun sekiz tekrarı:

;$_=$t;y(A-Z.! )'BITMAP DATA HERE';print

BITMAP DATA HEREyazı tipinin bir satırını kodlayan 29 bayt ile değiştirilir.


Yeni çözüm son derece güzel. Bunun 165 karakterde yapılabileceğini hiç düşünmemiştim.
ChristopheD

6

8086 Makine Kodu

190 Bayt (BIOS kullanarak 122 Bayt)

İşte Base64 kodlu WinXP / MSDos .COM dosyası:

M8COwCaKDoUEitEmxD4MAaCAAP7IfliK8MHgA7cK9ve9egEAZ
vy0APb3AUb6iMi0APb3AUb+x0YACg2DxQK+ggCK7qz24YvYJo
ohswjQ5LAwFACIRgBF/st18v7NdeRH/sp10sZGACS6cAG0Cc0
hw1AxCg0wMDAgMDA=

( Böyle bir şey kullanın ) metni çözmek ve "pbm.com" olarak kaydedin. Ardından, komut istemine şunu yazın:

kodlanacak pbm metni> outputfilename.pbm

WinXP makinemde hem standart komut istemini hem de DosBox V0.74'ü kullanarak bunu test ettim.

GÜNCELLEME

Bu sürüm 190 bayt ve Ilmari Karonen küçük yazı tipi (burada hiçbir bios erişim!) Kullanır: -

voAArf7Iflq7YwG/vgG6Cg20Bfbk9vIAZfsy5PbyAUX5Vqw48HQoLEFzCDQG/sAMGSQfM8
nQ6NfA0QPS6IjEsQSwJtDsENCq4vewMKrr04DDEF6A+7N1ycYFJLqzAbQJzSHDdnb/loIZ
mXZ2flmZ9QAAIJmZEZGCFb+ZmSFZmYUPDy9/kXf9ghPZeXkmWWllAAAgmZkRmZIVmRldKF
mfEgAAAHl2H5Zi+ZkWnicmmfIAICBQMQoNMDAwIDUKDQ==

Son derece güzel bir çözüm. Şu anda bu, yaklaşık 20 saat içinde verilecek ödülün yarışmacısıdır. Aferin!
ChristopheD

Bunun için montaj kodunuzu da gönderebilir misiniz?
Sir_Lagsalot

1
Sökme ve kodu test ettikten sonra, sadece bios tarafından sağlanan bir bitmap yazı tipi kullandığınız anlaşılıyor. Bu, programınızın meydan okuma için gerekli olmayan küçük harfler, semboller ve noktalama işaretleri çıkardığı gerçeğiyle doğrulanabilir. Bu nedenle, yazı tipi programınızın dışındadır ve onun tarafından saklanmaz (en azından bence).
Sir_Lagsalot

@ Skizz: Bunu onaylayabilir misin? Yine de son derece güzel bir çözüm sağlıyor, ancak spesifikasyonlara karşı biraz.
ChristopheD

1
@ChristopheD: JB, "Dış kütüphaneyi neyin oluşturduğuna dair uzun ve acılı bir tartışma yapacağımızı hissediyorum." - putsRuby'de harici bir kütüphane olduğunu iddia edebiliriz . Evet, işaretçi derefence aracılığıyla erişilen bios yazı tiplerini kullanır ( loadyazı tiplerini RAM'e alma işlemi yoktur ). Kuralları çok fazla bükmek. Eğer o sinir bozucu çocuklar için olmasaydı ben onunla kazanılmış olurdu ;-)
Skizz

6

Kabuk betiği (kod + veri = 295 karakter)

Umarım kuyruk, gzip ve dd "harici kütüphaneler" olarak sayılmaz. Farklı çalıştır echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm. Kullandığım yazı tipi, küçük yazı tiplerini 7.5 boyutunda olsa da, descender'ı Q'dan kesmek zorunda kaldım.

Örnek çıktı

HIZLI KAHVERENGİ FOX TEMİZ KÖPEK ÜZERİNDE ATLAMA.  GERÇEKTEN Mİ!

Kod (137 karakter)

i=`od -tu1|cut -c9-`
echo P4
for a in {0..7}
do for b in $i
do tail -2 $0|zcat|dd bs=1 count=1 skip=$((8*b+a))
done
done>8
wc -c 8
cat 8

Komut dosyasını tamamla

(Kullanım xxd -r orijinal dosyayı yeniden oluşturmak için )

0000000: 693d 606f 6420 2d74 7531 7c63 7574 202d  i=`od -tu1|cut -
0000010: 6339 2d60 0a65 6368 6f20 5034 0a66 6f72  c9-`.echo P4.for
0000020: 2061 2069 6e20 7b30 2e2e 377d 0a64 6f20   a in {0..7}.do 
0000030: 666f 7220 6220 696e 2024 690a 646f 2074  for b in $i.do t
0000040: 6169 6c20 2d32 2024 307c 7a63 6174 7c64  ail -2 $0|zcat|d
0000050: 6420 6273 3d31 2063 6f75 6e74 3d31 2073  d bs=1 count=1 s
0000060: 6b69 703d 2428 2838 2a62 2b61 2929 0a64  kip=$((8*b+a)).d
0000070: 6f6e 650a 646f 6e65 3e38 0a77 6320 2d63  one.done>8.wc -c
0000080: 2038 0a63 6174 2038 0a1f 8b08 0000 0000   8.cat 8........
0000090: 0000 ffed cdb1 0a83 3014 8561 910e 8e8e  ........0..a....
00000a0: 193b dca1 631f 2084 9353 6ba3 a3e0 e2a8  .;..c. ..Sk.....
00000b0: 2fe0 d8e1 22d8 276f 9a50 e813 940e fdb8  /...".'o.P......
00000c0: 70f9 a753 247f 7829 f0b5 b9e2 c718 2322  p..S$.x)......#"
00000d0: 1ba9 e9a8 9688 6895 892a 7007 f0fe 701e  ......h..*p...p.
00000e0: b879 ef48 6e8c aa4f 219c d984 750d 0d91  .y.Hn..O!...u...
00000f0: e9b2 8c63 d779 3fcf c3d0 f76d eb7c e2d2  ...c.y?....m.|..
0000100: 1880 d4d7 4b6e 9296 b065 49ab 75c6 cc92  ....Kn...eI.u...
0000110: 1411 63f6 7de7 3489 9031 847c 3c9a 531d  ..c.}.4..1.|<.S.
0000120: e9a1 aa8f 803e 01                        .....>.

açıklama

  • odstandart "sekizli dökümü" yardımcı programıdır. -tu1 seçenek ona ayrı ayrı baytların ondalık bir dökümünü üretmesini söyler (bash'ın asc (), ord (), .charCodeAt (), vb. Olmaması için yeterli bir geçici çözüm)
  • P4her bayta sekiz piksel (ikili P1ASCII biçiminde PBM dosyası yerine) paketleyen ikili biçimdeki PBM dosyasının sihirli numarasıdır . Bunun nasıl faydalı olduğunu göreceksiniz.
  • Son çıkış satırı başına, program, sondaki gzip sıkıştırılmış veri bölümünden sekiz piksel bayt (ASCII koduna ve satır numarasına karşılık gelir) kullanarak dd . ( tail -2 $0komut dosyasının son iki satırını ayıklar; sıkıştırılmış veriler bir 0x0a satır besleme baytı içerir.) Böylece, sekiz piksel tek bir karakterin genişliği olur. Desteklenen karakterler arasındaki boşlukları dolduran boş baytlar, hepsi aynı olduğu için kolayca sıkıştırılabilir.
  • Bütün bunlar "8" adlı bir dosyaya yazılmıştır. Tam olarak sekiz satır (ve bayt başına sekiz piksel) olduğundan bayt sayısı, çıktının piksel cinsinden genişliğidir. Çıktının yüksekliği de buna dahil edilirwc -c bayt sayımından sonra girdi dosya adını "8" yazdıracak şekilde de eklenir.
  • Başlık artık tamamlandığında, görüntü verileri yazdırılıyor. Bash, yalnızca son iki satırın daha önce gelen her şeyi yürüttükten sonra geçerli komutlar (sonuncusu aslında geçersiz UTF-8) olmadığını fark eder.
  • Ilmari Karonen'ın yaptığı gibi KZIP'i sadece veri bölümünü sıkıştırmak için kullandım bir için tüm sunulması Noel zorluk 12 Gün. Burada açıklandığı gibi, ZIP üstbilgi biçimini bir gzip üstbilgisiyle değiştirmek için bir onaltılı düzenleyici kullanmak esastır. CRC-32 ve orijinal ZIP başlığından dosya boyutu eklemek gereksiz görünüyor.

2
Gerçekten güzel (ve kısa) bir çözüm! Kabuk kodlamalarında dd, tail ve gzip kullanımı harici imho olarak kabul edilmemelidir.
ChristopheD

1
Bunun nasıl çalıştığına dair bir açıklama eklemek ister misiniz? Çok takdir edilecektir.
Bay Llama

2
Çok güzel, açıklama için çok teşekkürler. Ancak 'P4' versiyonunu kullanmak OP'nin “çok basit bir ASCII siyah beyaz bitmap formatı” dediğine gerçekten saygı duymuyor .
eregon

5

Piton 2, 248 247 bayt

s=raw_input();k=len(s);print"P1",k*8,8
for i in range(k*24):a=s[i/3%k];j=max(".!".find(a)+1,ord(a)-62)*3;print int("00080084IMVAENBSIFERBSUF4UFQQEMVDT4NAP4MNDSI9MRTMRBARA4NBQRAMNBE4E94NURDARDNRDMLD95DSL7"[j:j+3],32)>>(i/3/k*3+i%3)&1," 0"*(i%3/2*5)

Karakter başına 3 bayt olarak yazdırılabilir bir dize halinde paketlenmiş 3x5 yazı tipi kullanır. N küçük harf olmasına rağmen v bağlamında görünmüyorsa au ile karıştırılabilir.

Gerçek boyutu:
gerçek boyutu

Yakınlaştırılmış x3:
yakınlaştırılmış x3

Çıktı, meydan okumadaki örneğe göre bir P1 tipi PBM'dir. Eğlenceli bir mücadeleydi.


4

Yakut 1.9, 346 bayt (122 kod + 224 bayt veri)

İşte sonuç:

CODEGOLF

(Güzel, değil mi?)

z=0..7;puts"P1\n#{(s=gets).size*8} 8",z.map{|i|s.bytes.flat_map{|o|z.map{|j|'DATA'.unpack('Q<*')[o>64?o-63:o/46][i*8+j]}}*' '}

Yazı tipi figlet -f banner -w 1000 $LETTERSve bu komut dosyası tarafından oluşturuldu .

İle çalıştırın echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm.

Komut dosyası tüm satırları oluşturur ve bunları yazdırır.

İşte bir hexdump (kullanım xxd -r):

0000000: 7a3d 302e 2e37 3b70 7574 7322 5031 5c6e  z=0..7;puts"P1\n
0000010: 237b 2873 3d67 6574 7329 2e73 697a 652a  #{(s=gets).size*
0000020: 387d 2038 222c 7a2e 6d61 707b 7c69 7c73  8} 8",z.map{|i|s
0000030: 2e62 7974 6573 2e66 6c61 745f 6d61 707b  .bytes.flat_map{
0000040: 7c6f 7c7a 2e6d 6170 7b7c 6a7c 271c 1c1c  |o|z.map{|j|'...
0000050: 0800 1c1c 0000 0000 001c 1c1c 0008 1422  ..............."
0000060: 417f 4141 003f 4141 3f41 413f 003e 4101  A.AA.?AA?AA?.>A.
0000070: 0101 413e 003f 4141 4141 413f 007f 0101  ..A>.?AAAAA?....
0000080: 1f01 017f 007f 0101 1f01 0101 003e 4101  .............>A.
0000090: 7941 413e 0041 4141 7f41 4141 001c 0808  yAA>.AAA.AAA....
00000a0: 0808 081c 0040 4040 4041 413e 0042 2212  .....@@@@AA>.B".
00000b0: 0e12 2242 0001 0101 0101 017f 0041 6355  .."B.........AcU
00000c0: 4941 4141 0041 4345 4951 6141 007f 4141  IAAA.ACEIQaA..AA
00000d0: 4141 417f 003f 4141 3f01 0101 003e 4141  AAA..?AA?....>AA
00000e0: 4151 215e 003f 4141 3f11 2141 003e 4101  AQ!^.?AA?.!A.>A.
00000f0: 3e40 413e 007f 0808 0808 0808 0041 4141  >@A>.........AAA
0000100: 4141 413e 0041 4141 4122 1408 0041 4949  AAA>.AAAA"...AII
0000110: 4949 4936 0041 2214 0814 2241 0041 2214  III6.A"..."A.A".
0000120: 0808 0808 007f 2010 0804 027f 0027 2e75  ...... ......'.u
0000130: 6e70 6163 6b28 2751 3c2a 2729 5b6f 3e36  npack('Q<*')[o>6
0000140: 343f 6f2d 3633 3a6f 2f34 365d 5b69 2a38  4?o-63:o/46][i*8
0000150: 2b6a 5d7d 7d2a 2720 277d                 +j]}}*' '}

Goruby kullanırken 93 bayt kod alır:

ps"P1\n#{(s=gt).sz*8} 8",8.mp{|i|s.y.fl{|o|8.mp{|j|'DATA'.ua('Q<*')[o>64?o-63:o/46][i*8+j]}}*' '}

ZLib kullanarak veri boyutunu 224 yerine 142 bayta kırpın, ancak koda 43 bayt ekler, böylece 307 bayt:

#coding:binary
require'zlib';z=0..7;puts"P1\n#{(s=gets).size*8} 8",z.map{|i|s.bytes.flat_map{|o|z.map{|j|Zlib.inflate("DATA").unpack('Q<*')[o>64?o-63:o/46][i*8+j]}}*' '}

Goruby kullanırken toplam 268 verir:

#coding:binary
rq'zlib';ps"P1\n#{(s=gt).sz*8} 8",8.mp{|i|s.y.fl{|o|8.mp{|j|Zlib.if("DATA").ua('Q<*')[o>64?o-63:o/46][i*8+j]}}*' '}

2

Java 862 826:

İşte farklı bir yaklaşım. Bence 'awt' harici lib olarak sayılmaz.

import java.awt.*;
class B extends Frame{String s="ABCDEFGHIJKLMNOPQRSTUVWXYZ .!";int l=29;static Robot r;int[][][]m=new int[l][8][8];
public void paint(Graphics g){for(int y=0;y<8;++y){int py=(y<3)?y:y+1;for(int a=0;a<l;++a)
for(int x=0;x<8;++x)
m[a][x][y]=(r.getPixelColor(8*a+x+17+x/4,py+81)).getRGB()<-1?1:0;}
System.out.println("P1\n"+(getTitle().length()*8)+" 8");
for(int y=0;y<8;++y){for(char c:getTitle().toCharArray()){int a=s.indexOf(c);
for(int x=0;x<8;++x)System.out.print(m[a][x][y]);}
System.out.println();}
System.exit(0);}
public B(String p){super(p);
setBackground(Color.WHITE);
setSize(400,60);
Label l=new Label(s);
l.setFont(new Font("Monospaced",Font.PLAIN,13));
add(l);
setLocation(9,49);    
setVisible(true);}    
public static void main(String a[])throws Exception{r=new Robot();    
new B(a[0]);}}

Ve ungolfed:

import java.awt.*;

class PBM extends Frame
{
    String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ .!";
    int l=29;
    Robot robot;
    int[][][] map = new int[l][8][8];

    static boolean init = false;

    public void paint (Graphics g)
    {    
        for (int y = 0; y < 8; ++y)    
        {    
            int py = (y < 3) ? y : y +1;    
            for (int a = 0; a < l; ++a)
            {    
                for (int x = 0; x < 8; ++x)    
                {    
                    map[a][x][y] = (robot.getPixelColor (8*a+x+17+x/4, py+81)).getRGB () < -1 ? 1 : 0;    
                }    
            }    
        }

        System.out.println("P1\n"+(getTitle().length()*8)+" 8");

        for (int y = 0; y < 8; ++y) {    
            for (char c : getTitle ().toCharArray ()) {    
                int a = s.indexOf (c);    
                for (int x = 0; x < 8; ++x) {    
                    System.out.print (map[a][x][y]);    
                }
            }
            System.out.println ();
        }
        System.exit (0);
    }   

    public PBM (String p) throws Exception    
    {    
        super (p);    
        robot = new Robot ();    
        setBackground (Color.WHITE);    
        setSize (400, 60);    
        Label l=new Label(s);    
        l.setFont (new Font ("Monospaced", Font.PLAIN, 13));
        add(l);
        setLocation (9,49);
        setVisible (true);
    }

    public static void main (String args[]) throws Exception
    {
        new PBM (args[0]);
    }    
}

Robot, Java'nın getPixel'i çağırmanın ilginç bir yoludur. Alfabeyle bir Etiket oluşturuyorum ve her harf için bir pikselin nerede olduğunu ölçüyorum.

Boya yönteminde int py = (y < 3) ? y : y +1;ve(8*a+x+17+x/4, py+81) yazı tipi içindeki konumunu ayarlamak için karmaşık bir yoldur. Huuuh! aksi takdirde 9 satıra ihtiyacı vardır ve her 4 harfte bir yatay olarak ek piksel vardır. Deneme yanılma beni bu çözüme getirdi.

Daha sonra PBM'nin başlığı ve mesajın her satırı yazılır. Mesaj çerçevenin başlığı olarak iletilir.

Bu kadar. En kısa kod değil, elle yazı tipi boyama gerekli değildi.

Belki BeanShell veya Scala'da daha kısa olabilir.

Ve şimdi - nasıl görünüyor?

java B "JAVA.CAFE BABE" > jcb.pbm

Birden fazla yakınlaştırma uygulandı: java.cafe bebeğim PNG

yakınlaştırılmamış: javacafe bebeğim jpg

Karakter sayısının karıştırılan Perl çözeltisinden karakter sayısı olmadığı anlamına gelmez.

(biraz daha golf oynadı. Bir İstisna bildirimini önleyen Robot'u statik hale getirin.)


Orijinal yaklaşım, güzel yapılır!
ChristopheD

1
Özgünlük için +1, ancak eww ... bir bitmap'i ölçeklendirecekseniz, en yakın komşu enterpolasyonunu kullanın.
Ilmari Karonen

Kullandığım eog(Gnome Göz) ve bir ekran görüntüsü. jpgÖlçeklendirilmemiş bir sürüm yükleyeceğim; belki tarayıcınız en yakın komşu enterpolasyonunu kullanır :).
kullanıcı bilinmiyor

1

C ++ KAZANMAK İÇİN BÜYÜK

Kendi bit eşlemli yazı tipimle, C ++ 'da tam özellikli bir PPM çizim programı yazdım. Gerekli olmayan tüm işlevleri sıyırmak bile, yazı tipinin tanımı nedeniyle buradaki cevaplara kıyasla hala çok büyük.

Her neyse, işte HELLO WORLD için çıktı: resim açıklamasını buraya girin

Ve kod:

ppmdraw.h

#ifndef PPMDRAW_H
#define PPMDRAW_H

#include <fstream>
#include <sstream>
#include <map>
#include <bitset>
#include <vector>

struct pixel{
    unsigned char r;
    unsigned char g;
    unsigned char b;

    bool equals(pixel p){
        return (r == p.r && g == p.g && b == p.b);
    }
};

class PPMDraw
{
    public:
        PPMDraw(int w, int h);

        virtual ~PPMDraw();

        void fill(unsigned char r, unsigned char g, unsigned char b);

        void set_color(unsigned char r, unsigned char g, unsigned char b);

        void draw_point(int x, int y);

        void draw_char(int x, int y, char c);
        void draw_string(int x, int y, std::string text);

        bool save(std::string file);

    private:

        int width;
        int height;

        pixel * image;

        std::vector<bool> checked;

        unsigned char red;
        unsigned char green;
        unsigned char blue;

        void init_alpha();
        std::map<char, std::bitset<48> > font;

};

#endif // PPMDRAW_H

ppmdraw.cpp

#include "PPMDraw.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cmath>
#include <map>
#include <bitset>
#include <vector>

// standard constructor
PPMDraw::PPMDraw(int w, int h){
    width = w;
    height = h;

    // make an array to hold all the pixels, r, g, b for each
    image = new pixel[width * height];

    // a bitset to use for functions that have to check which pixels have been worked on
    checked = std::vector<bool>();
    for(int i = 0; i < width * height; i++){
        checked.push_back(false);
    }

    init_alpha();
}


PPMDraw::~PPMDraw(){
    if(image != nullptr){
        delete[] image;
    }
}



void PPMDraw::fill(unsigned char r, unsigned char g, unsigned char b){
    for(int i = 0; i < width * height; i++){
        image[i + 0] = pixel{r, g, b};
    }
}

void PPMDraw::set_color(unsigned char r, unsigned char g, unsigned char b){
    red = r;
    green = g;
    blue = b;
}

void PPMDraw::draw_point(int x, int y){
    if(x >= 0 && x < width && y >= 0 && y < height){
        image[y * width + x] = pixel{red, green, blue};
    }
}

void PPMDraw::draw_char(int x, int y, char c){
    std::bitset<48> letter = font[c];
    int n = 47;
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 8; j++){
            if(letter[n]){
                draw_point(x + i, y + j);
            }
            n--;
        }
    }
}
void PPMDraw::draw_string(int x, int y, std::string text){
        for(unsigned int i = 0; i < text.length(); i++){
            draw_char(x + 6 * i, y, text[i]);
        }

}



bool PPMDraw::save(std::string file){
    std::ofstream save(file.c_str(), std::ios_base::out | std::ios_base::binary);
    if(save.is_open()){
        save << "P6" << std::endl;
        save << width << " " << height << std::endl;
        save << "255" << std::endl;
        unsigned char * temp = new unsigned char[height * width * 3];
        for(int i  = 0; i < height * width; i++){
            temp[i * 3 + 0] = image[i].r;
            temp[i * 3 + 1] = image[i].g;
            temp[i * 3 + 2] = image[i].b;
        }
        save.write(reinterpret_cast<const char *> (temp), height*width*3*sizeof(unsigned char));
        delete temp;
        save.close();
        return true;
    }else{
        return false;
    }


}

void PPMDraw::init_alpha(){
    // Define a simple font for drawing text
    font[' '] = std::bitset<48>  (std::string("000000000000000000000000000000000000000000000000"));
    font['!'] = std::bitset<48>  (std::string("000000000000000011110110000000000000000000000000"));
    font['"'] = std::bitset<48>  (std::string("000000001100000000000000110000000000000000000000"));
    font['#'] = std::bitset<48>  (std::string("001010001111111000101000111111100010100000000000"));
    font['$'] = std::bitset<48>  (std::string("001001000101010011111110010101000100100000000000"));
    font['%'] = std::bitset<48>  (std::string("000000100100110000010000011000001000010000000000"));
    font['&'] = std::bitset<48>  (std::string("000111001110001010110010110011000000001000000000"));
    font['\\'] = std::bitset<48>  (std::string("100000000110000000010000000011000000001000000000"));
    font['('] = std::bitset<48>  (std::string("000000000000000001111100100000100000000000000000"));
    font[')'] = std::bitset<48>  (std::string("000000001000001001111100000000000000000000000000"));
    font['*'] = std::bitset<48>  (std::string("010010000011000011100000001100000100100000000000"));
    font['+'] = std::bitset<48>  (std::string("000100000001000001111100000100000001000000000000"));
    font[','] = std::bitset<48>  (std::string("000000000000000000000110000000000000000000000000"));
    font['-'] = std::bitset<48>  (std::string("000100000001000000010000000100000001000000000000"));
    font['.'] = std::bitset<48>  (std::string("000000000000000000000100000000000000000000000000"));
    font['/'] = std::bitset<48>  (std::string("000000100000110000010000011000001000000000000000"));
    font['0'] = std::bitset<48>  (std::string("011111001000001010000010100000100111110000000000"));
    font['1'] = std::bitset<48>  (std::string("000000001000001011111110000000100000000000000000"));
    font['2'] = std::bitset<48>  (std::string("010011101001001010010010100100100111001000000000"));
    font['3'] = std::bitset<48>  (std::string("010001001000001010000010100100100110110000000000"));
    font['4'] = std::bitset<48>  (std::string("111100000001000000010000000100001111111000000000"));
    font['5'] = std::bitset<48>  (std::string("111001001001001010010010100100101001110000000000"));
    font['6'] = std::bitset<48>  (std::string("011111001001001010010010100100101000110000000000"));
    font['7'] = std::bitset<48>  (std::string("100000001000000010000110100110001110000000000000"));
    font['8'] = std::bitset<48>  (std::string("011011001001001010010010100100100110110000000000"));
    font['9'] = std::bitset<48>  (std::string("011000001001000010010000100100000111111000000000"));
    font[':'] = std::bitset<48>  (std::string("000000000000000001000100000000000000000000000000"));
    font[';'] = std::bitset<48>  (std::string("000000000000000001000110000000000000000000000000"));
    font['<'] = std::bitset<48>  (std::string("000000000001000000101000010001000000000000000000"));
    font['='] = std::bitset<48>  (std::string("001010000010100000101000001010000000000000000000"));
    font['>'] = std::bitset<48>  (std::string("000000000100010000101000000100000000000000000000"));
    font['?'] = std::bitset<48>  (std::string("010000001000000010001010100100000110000000000000"));
    font['@'] = std::bitset<48>  (std::string("011111001000001010111010101010100111001000000000"));
    font['A'] = std::bitset<48>  (std::string("011111101001000010010000100100000111111000000000"));
    font['B'] = std::bitset<48>  (std::string("111111101001001010010010100100100110110000000000"));
    font['C'] = std::bitset<48>  (std::string("011111001000001010000010100000100100010000000000"));
    font['D'] = std::bitset<48>  (std::string("111111101000001010000010100000100111110000000000"));
    font['E'] = std::bitset<48>  (std::string("111111101001001010010010100100101000001000000000"));
    font['F'] = std::bitset<48>  (std::string("111111101001000010010000100100001000000000000000"));
    font['G'] = std::bitset<48>  (std::string("011111001000001010000010100010100100110000000000"));
    font['H'] = std::bitset<48>  (std::string("111111100001000000010000000100001111111000000000"));
    font['I'] = std::bitset<48>  (std::string("100000101000001011111110100000101000001000000000"));
    font['J'] = std::bitset<48>  (std::string("000011000000001000000010000000101111110000000000"));
    font['K'] = std::bitset<48>  (std::string("111111100001000000010000001010001100011000000000"));
    font['L'] = std::bitset<48>  (std::string("111111100000001000000010000000100000001000000000"));
    font['M'] = std::bitset<48>  (std::string("111111101000000001100000100000001111111000000000"));
    font['N'] = std::bitset<48>  (std::string("111111100100000000100000000100001111111000000000"));
    font['O'] = std::bitset<48>  (std::string("011111001000001010000010100000100111110000000000"));
    font['P'] = std::bitset<48>  (std::string("111111101001000010010000100100001111000000000000"));
    font['Q'] = std::bitset<48>  (std::string("011111001000001010001010100001000111101000000000"));
    font['R'] = std::bitset<48>  (std::string("111111101001000010010000100110001111011000000000"));
    font['S'] = std::bitset<48>  (std::string("011000101001001010010010100100101000110000000000"));
    font['T'] = std::bitset<48>  (std::string("100000001000000011111110100000001000000000000000"));
    font['U'] = std::bitset<48>  (std::string("111111000000001000000010000000101111110000000000"));
    font['V'] = std::bitset<48>  (std::string("111110000000010000000010000001001111100000000000"));
    font['W'] = std::bitset<48>  (std::string("111111100000001000001100000000101111111000000000"));
    font['X'] = std::bitset<48>  (std::string("110001100010100000010000001010001100011000000000"));
    font['Y'] = std::bitset<48>  (std::string("110000000010000000011110001000001100000000000000"));
    font['Z'] = std::bitset<48>  (std::string("100001101000101010010010101000101100001000000000"));
    font['['] = std::bitset<48>  (std::string("000000001111111010000010100000100000000000000000"));
    font['\''] = std::bitset<48>  (std::string("100000000110000000010000000011000000001000000000"));
    font[']'] = std::bitset<48>  (std::string("000000001000001010000010111111100000000000000000"));
    font['^'] = std::bitset<48>  (std::string("001000000100000010000000010000000010000000000000"));
    font['_'] = std::bitset<48>  (std::string("000000100000001000000010000000100000001000000000"));
    font['`'] = std::bitset<48>  (std::string("000000001000000001000000000000000000000000000000"));
    font['a'] = std::bitset<48>  (std::string("000001000010101000101010001010100001111000000000"));
    font['b'] = std::bitset<48>  (std::string("111111100001001000010010000100100000110000000000"));
    font['c'] = std::bitset<48>  (std::string("000111000010001000100010001000100001010000000000"));
    font['d'] = std::bitset<48>  (std::string("000011000001001000010010000100101111111000000000"));
    font['e'] = std::bitset<48>  (std::string("000111000010101000101010001010100001101000000000"));
    font['f'] = std::bitset<48>  (std::string("000100000111111010010000100100000000000000000000"));
    font['g'] = std::bitset<48>  (std::string("001100100100100101001001010010010011111000000000"));
    font['h'] = std::bitset<48>  (std::string("111111100001000000010000000100000000111000000000"));
    font['i'] = std::bitset<48>  (std::string("000000000000000001011110000000000000000000000000"));
    font['j'] = std::bitset<48>  (std::string("000000100000000100000001010111100000000000000000"));
    font['k'] = std::bitset<48>  (std::string("111111100000100000010100001000100000000000000000"));
    font['l'] = std::bitset<48>  (std::string("000000000000000011111110000000000000000000000000"));
    font['m'] = std::bitset<48>  (std::string("000111100001000000001000000100000001111000000000"));
    font['n'] = std::bitset<48>  (std::string("001111100001000000010000000100000001111000000000"));
    font['o'] = std::bitset<48>  (std::string("000111000010001000100010001000100001110000000000"));
    font['p'] = std::bitset<48>  (std::string("001111110010010000100100001001000001100000000000"));
    font['q'] = std::bitset<48>  (std::string("000110000010010000100100001001000011111100000000"));
    font['r'] = std::bitset<48>  (std::string("000000000011111000010000000100000000000000000000"));
    font['s'] = std::bitset<48>  (std::string("000000000001001000101010001010100010010000000000"));
    font['t'] = std::bitset<48>  (std::string("000000000010000011111110001000000000000000000000"));
    font['u'] = std::bitset<48>  (std::string("000111000000001000000010000000100001110000000000"));
    font['v'] = std::bitset<48>  (std::string("000110000000010000000010000001000001100000000000"));
    font['w'] = std::bitset<48>  (std::string("000111100000001000000100000000100001111000000000"));
    font['x'] = std::bitset<48>  (std::string("001000100001010000001000000101000010001000000000"));
    font['y'] = std::bitset<48>  (std::string("001100000000100000000111000010000011000000000000"));
    font['z'] = std::bitset<48>  (std::string("010001100100101001010010011000100000000000000000"));
    font['{'] = std::bitset<48>  (std::string("000000000000000001101100100100100000000000000000"));
    font['|'] = std::bitset<48>  (std::string("000000000000000011111110000000000000000000000000"));
    font['}'] = std::bitset<48>  (std::string("000000000000000010010010011011000000000000000000"));
    font['~'] = std::bitset<48>  (std::string("000100000010000000010000000010000001000000000000"));
}

main.cpp

#include "PPMDraw.h"
#include <iostream>

int main(){
    // ask for input
    std::string input;
    std::cout << "ENTER YOUR TEXT" << std::endl;
    getline(std::cin, input);
   // get size for image
  int width = input.size() * 6;
   PPMDraw image = PPMDraw(width, 8);
   image.fill(255, 255, 255);
   image.set_color(0, 0, 0);
   image.draw_string(0, 0, input);
   image.save("text.ppm");
}

Makefile

CC = g++
CFLAGS = -Wall -c -std=c++11
LFLAGS = -Wall
OBJS = main.o PPMDraw.o

list: $(OBJS)
    $(CC) $(LFLAGS) $(OBJS) -o text2ppm

main.o: PPMDraw.h
    $(CC) $(CFLAGS) main.cpp

PPMDraw.o: PPMDraw.h
    $(CC) $(CFLAGS) PPMDraw.cpp

clean:
    rm *.o main

İlgileniyorsanız, tam PPMDraw kütüphanesi burada :


1
Yazı tiplerini çok kullanışlı buldum!
Ludwik

1

SmileBASIC, 231 bayt

LINPUT C$?"P1
?8,LEN(C$)*8WHILE""<C$A=ASC(SHIFT(C$))D=ASC("*N.JZ`;O:²ÞøäüÄho"[A-65+12*(A<34)+47*(A<47)])FOR I=0TO 4B$=BIN$(VAL("7535712074617252"[D>>5<<1OR 1AND D>>I]),8)WHILE""<B$?POP(B$),
WEND?NEXT?"0 "*24WEND

resim açıklamasını buraya girin

Her karakter 8 kombinasyonluk bir "palet" ten seçilen sadece 2 farklı satır deseni içerir. Her sembolün verileri, palet ayrı olarak depolanacak şekilde 1 baytta depolanır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.