mojo-magick-0.5.6/0000755000175000017500000000000012542772650013271 5ustar sophiesophiemojo-magick-0.5.6/mojo_magick.gemspec0000644000175000017500000000262012542772650017115 0ustar sophiesophie$:.push File.expand_path("../lib", __FILE__) require "mojo_magick/version" post_install_message = <= 1.1.3, < 2.0) simplecov (0.7.1) multi_json (~> 1.0) simplecov-html (~> 0.7.1) simplecov-html (0.7.1) PLATFORMS ruby DEPENDENCIES mojo_magick! rake rspec-expectations simplecov mojo-magick-0.5.6/Rakefile0000644000175000017500000000057012542772650014740 0ustar sophiesophierequire 'rubygems' task 'default' => :test desc "Default: run tests" task :test do require 'simplecov' SimpleCov.start require 'rake/runtest' files = Dir.glob(File.join(File.dirname(__FILE__), 'test/*_test.rb')) files.each do |f| Rake.run_tests f end end desc "Build gem" task :build do `rm mojo_magick-*.gem` puts `gem build mojo_magick.gemspec` end mojo-magick-0.5.6/test/0000755000175000017500000000000012542772650014250 5ustar sophiesophiemojo-magick-0.5.6/test/fixtures/0000755000175000017500000000000012542772650016121 5ustar sophiesophiemojo-magick-0.5.6/test/fixtures/zero_byte_image.jpg0000644000175000017500000000000012542772650021755 0ustar sophiesophiemojo-magick-0.5.6/test/fixtures/not_an_image.jpg0000644000175000017500000002342112542772650021245 0ustar sophiesophieFnoH0yxCHtϮ|}M/Wisagt!a2?9Cnj04A[EL??9'l6JLk1xsf 9&UZHJh_Bj?*n26ÏҦ=cߢёl_"yǮ`aw@;++ fE1-q'հ88*+gz?W!CժnHy0/ZPkvNAXQ{M`nvj6 /Xٌ^{[ 4Pɡc)s&l`uaEKYDt9@ñ%=p,o2Q쨝\!1E)/`EjЕL厪w8U r=ƛyMl`]Pm-<%SgC]QtWwf/m'~zd@?*9* b`e-1<(deKSS~f68ۈd)ںK鏚DOnrw>c~wY*nN;,ի7:H=6K^}fFGUd!yZ.и ܻ؅(i!8r2LzM~zU3.Z擖7cTGntG{a}\Appߒ\}{ Ce aߏ\JS2>FLGDRaZ?$@\Lrw)B @hQCO\ (=@ 5 6;P#cQsRpC#XEB8L)b)NIj jk6+n UTIL x$jRPf Qo̼j7[3nK)eeDPIyOA,u;UP._Aߌr;lgv/` Y:m~G &-8S&wbÈiy2B]J۷Bד=Bb91᳈ i`+c{*vFf;@)2H@(.,锱!;X[noR2gya$C鵒uJNh${o8E=J$$rB  rH&-Gl4뺾;v$o.E d_Y׮BJ#H?x nw˘[A,M0櫍k%02 V.`v]{c6ć΁,!0Ni-6XWE!1[D M79t8ZCr:@c{XrY'zQ3ÞU_>..S/oO\ZU4(6WkTt]WMEhgK j"UiR@u(*ҙ:DtĬ &e_ȞOdם/ A8 v:ڑx#'nB\ޯW;<`̤/CIZA8!$0 a6ZSˑ#nhGd,wQzY6C24aHPה]z!g3>Ҽ[Ulf/ɑ~$.Z2j"@J?M6Em,X;" -GQuU. V0X旞+̴CKQQylNlWA~G16Km(LyxS,3ܲ8"+"&p#=K]ĭBGxԬPo7;r8~ QN-L0`@}r27χVo?(}Vl@3PUaA`-y䫙7≈W.ȣR$w>O &v `$u覼l\q8PYwp'N,KM|l`Z0F}`_0JpQWƧn]w[ X5_3xS:Yz# lY]arU k'9?^YgHĔvB?}[.D|׮s{IiƴdEI4gib>憾׊Up2,:Fp3֯'}0x\l!'@57F~Q4+D,xmOÝ tKJj;O$DH IH͡=+6$MwTdRPK"N I naF"Ŷ\ A.6ճxh\*1J[7f%*]̻>W$ KjiAFq bN{YDN PbŒ0eJUzQQLGf%z8$E~K>efdrk ՝Phу,FQgXHZ6%+ @1UcjEfbdEQ{}pbxKaE0jOYbK%u8ҧ+wa ܷG_2 W(]@*u2JUkꚭ}E-s?~wecZ4gVQ~&0:D`ׯA!K*˃lћ|GuOo"-̾urX,.ngb8awa{ώ5swK/c'6m\ k],$-p4m++3,oza?N*叮!>`ٌiX:sF*{sóh<4w8DsIe1FK^^C>6GIꛏvN)OXIԥ N`d~JK\U m{mz Cʵs)fYcSn0):e,FWBR~PqRNz?aTzmV/2zb"[ؼm7wŇæ)v9(L7'NMJtʉc-PgW0|ĄD:JJZ+yCyUۉdƕ~F=%5::tj^ǼYBJ,r.U uN](>M qFf<:"o;kx͚"eci6uG+SbB}ON[Ued9X5߱RoɈ}gL4Qkj' ̀vB x?T`8F7;kf1_:WR"RE(.7?"+=@'EI ,Rr7Sw(N"K<e™A/";Ϝ5!h)n]Ek3;Nifh9}F$k#' Ca g<ci,wZ{ Ymv(b ^:R9'!&V0LA=_t=F\랻X3ugl7K((kԢnIGu1Ƙ5݅8H@>hESWʸuXRAn "V #H\:QtR3XM2;n&ӞU6 ;ñoXA0w^kfMȎ8Գ>+GEu&{-x&|,?ﳠl]τdK8p$>~Yۈ7 \vf,yJ1MT c% ?Z A胕EhI-v[7 虷;#7TG|R(PvMT:Y\睻Z\@ѼRDvNv,JgńV'EbBdэ$)\*q=ig.\B@c+8P޺4dfxE]T-hD ^1a}7ςH rC;G38 ?aǂ8#)uJ.ﳻ a*C[c{b'I"b 4*tT Ri6LYUx@n!Ws=C^y$q˼TF H{F'fc#YZ;*Eh7Lr=yUiچ1MFTDP?hklS2)SV|1ɢkv)B:$z&sknfhB Q9FIlz'lgI ن 營n'"} qyhHG)@΁;?$}-kW,_BMPv4i/0{}$OS-wŲ%.q<`̡Y ,@YdWHlO]l+Wgy֑ :sU`rwfN%"m4fN19XK|soX*1}QB?>ތSU)w{pđ-sDjEwcv[}B-8%ӽ5<6WsT`J Mo``<&^Im͓G kV0çEǨ#~}[g2KDE!vҝ=Ӻ jLr{ԝ[ OP vp5KU/0;nLi\l9 pW8ZwLAČmH ֱ~CVf8/։SZ !z > ؎K f'̵keάoa]zHJ{ sMKÇ9wJ8ACo˨+'/}֒) IgTn/T+KY֖{xN7Qb|Fa`%@C|9R[ Fupu<|K'a *rPU#z:ٿ_4s ?D4FgPj[W|'{Ӧ'u)}9p̕bCp9ґ8[=f"c'%MY ʻo W 0}X.R=d9Ư! Y RBK"Jcx0Nr]+uYO=6qV^/k-BA~jV.EcWBIdN:0i*\-zHtwtuņ1:ghS3%m?C՚yS0a~p8kYRz}rc~=ˎmK}ԋig-nP2I*nB@%Xd< Y4U^dHVh%z%Mʱ#7̢+UcF?As8YEi}E;1yGMXE/ 퓖!=nt/T]’99~k1)U ڥ̅],߉jqzjx gAܡ@EQg+Yb09<(c+t|Fw;/<4MJIK k x9j6\#;Wr65,+As&$ G׬b GVOߙs/.p5i'3}@^*a}%$ .M .nb_2VS7 WX7cOV㡛6)˜$"soZW$˹´>|m(0 Ey+"6>)ͱyMߐNWM'. 0 f~IP㎶UPMK`#KV17%!`t54{ǃsS6;*F6RD |وz[(`9[?o6FZhv %L'ȸGl×L8CiMí ίBI_ vF$;""s1ODM5i HzF yDI\xK$+Îh1?|BF=^m7ϖܳت&;d䋩"ĝCYT\7UӼ?;$|y^<$lE9$Jd2';=UVto '+މ,/''3+\}YZa7jƆ60^K.q0Jj՛oAϠ>CqO}jݦL6,IV'> ,s80o$DV` 3> bN:fbgXC-@m"6۪ZMBc”} )QC2 kBO֢qwoȣTuȗ7m \|~);Y<¿z'V!.kɕk|ŒBaLU9&X۰hFE? t -Nmɧu{'ɼS1Bq~ܱ;nY Bpci[Cz-fN܄#jU .GܥPp;FOO@q"5Œ&СrvIx^PP'1^C°<-[g*pg0nh@g5~*\#uRH^ԌnSI4cB@-t匎S;VuIO7lvE1<^^S*%T ʪ*Wq 4eVYТ D6gtq- l圁TdJN]F.l5H|MB-BUSn'E qc鴮YDcuUm*Á(W<P|jxz\2= \VMi}rEq>뙬d5ȠΥ` w<536j$`˵$osa.nVi~r 9(x;Hنཥw%[wT[^B$Ӫ䪼NGOug]&;j`s1jyd8RiO3],јbr/BmCuiW{MRK Ҕ7rFT ʿ.~NtY*o iҪ-+/.WTnef@I^)D?h$NqZUK~Xiu2!C3LY@{k`r|}֚YP{2f2[@)o!əTnCQ&wPI5jZ;lrWCy)Ąka-mr/N _TivSFZ߄|Ҡ):#I w!5ŀqၧ7lI 'q5M]$_EZXuDRe;⅄}pb}SIf2zPKX<~&mt jBJH Nq1a#"Zh9AF n"Ap4_SMwc#n oM%:_̊Jfad [ qMleڪ@:n1$mf.LwV0*ne=śB}M,FłӒ[ F.5l:Ѫs BÅ{GRX며[r ''^ :.Oz<)U{ÿ5/V~Y)m$_| >DM7VwXQ$(rs\^IHC=E^iEҦ "2Ɋ/8TUnqjYg(ѣg!JC^ };''9$ <+[/Ɯo!|^ǜ/q9;w{; gTF=6S"K8F_[vџ(I)v’pŃPH/`AX% ьsUK1>+mݸٻ1M gFl&fU,yyҵqR@3yeo1/z^0D^qN{56{N d@u̠*?A+:-O.s@FQ:QmYSʥ28<_?jLX׿^bֽ|% %ZS9<ű[KE\`: 8 .wK8ۓSw\(֛'A(Ix'qGS,4O4 $]KS6}ΗD(lH-ěɔ \BlVko%4+UaLh[5hwꓶ^ iA.R8ޣM.mojo-magick-0.5.6/test/fixtures/5742.jpg0000644000175000017500000007150512542772650017234 0ustar sophiesophieJFIF``C   %# , #&')*)-0-(0%()(C   (((((((((((((((((((((((((((((((((((((((((((((((((((M" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?ޜ D3NrN L .yn/ln-[[F=qi 0^ּV] !_ SYZzQQڔq}iu'Rd棟8cdpjRzvH=0)yMzgҗvj8~)IIrO4CM*d^ IN?G`9$zfNN}*0IlSxgQГM49hi“7-Fr}Gv5 ƜtH5I Ƚ8֖:Zڀ'}Eo# 2?v&eq'2ɏ}yI4(tE;w';Uњnkpj)GT \VVVivj,ހ%q^?͝ab=TB*X2N;(e~]i[ךGQ};S%d })H+ҕrJ:XF8;p@< \&H#񧪃;gO=@>VcrGҢS溔:]OY?Fgsq+ռ4 Fm#dtnv<*zcKV*.NJNAI`~ 4r7h8?/nך`hQpR3@<ZcN?M1 sJHQiwD5f0#] $T ~T2HvƼkQHS{zUEs39K\$g0_SZk++nWwbL&i$O kSo]TL3N3>HAfA5Zhnc *bcp3֣(4đ(4is@ɷSfE)!"o,"Im؃JpIJ=\ㅘ GsY=;V;"K)N0*8'OPReNrsN@qu\tL~^OJpaҙQ<ҰOJ>j~ǥ8!W08P;ixPn͈9Saܚ;'ɥQ F%FY(C~ mIWUPO_5E)\dg"vO[pҪBSj*u?9$+G1mmXԟy#}$ƺ_b8ma\<۽g- 3M'3uOJa;Β.sAw6;M0lz#)e'Mcua\?;jU=XYzR#`N㚖˷\cS#nhzXYF~c?{z©+舔UkúXx`v]I=M`0)3[X㜹إTHM-HM!<4YϽIDBu&,&њ|ow@t-c?rpqW{H>Ӣ*ȢUy0,U"H${ҟN*-0NݓVm\fӠGB+?q` t.Zt)1҃*u^jR"*n?R?Hpܭ\GFP%J6܃ec+ ##>Jٗòuga,Y\_Tػ[8CGA>h^+x#Ilgbc۰2$05 Je$gC!,V;6d|G>ϷJ_!#" q)-3078.XIMA'#5\1&xʆ'8"&_Mpsl']qA8J:3JƉs0$~UH>f҂qgPɧqԞb Ɏ.vZI@?i~Uz(<kfP/v5#h?};R@SG&t)nfHbv,zF?wa7b}'O{%bNf{]11$Q(HmUlX-Iަm圹&M75D&A>^EIoåjOPXjT49g>M+cQG<+Aϯ_e.swc*6RRHX!u6["(_YxO$45]K>-پKNO֐ko j!<~m~ Lz&VgS<[E$0XN;~5噰I!G~fP\M59U>TV|pG,O@(&y#M9Z(mnd]F,b-&ֹqaGGCmM4i3Yi8ϩnsހ4$~j g{ q=bsIy.Zrᙏ9L4|e&};R?!`$niARcL.ix4oZ478wAm8nPfjsC.1ܿQȤ]Nȩ#FpG"OfѸMxGSSKYT@ &;;:z:^ьsHpsN\ 'i${UM2rL[y(+mllhc*M#谜2t˛Y=sMӬxK{(%|胁^jffX?>n+=\V6Xׅ誜vsX!XgAr2@fr9<'Y aB=;NGjWmmB31wRb^Z= e0E"(Y{m>\rMrPIo1Q=G+"17mIn.0wvzE9ǩ}ӽ/N9G>9'u&e̸"5?1֫h:hEK%a![W1>x=h34Vd)4I@!ja4!۱IiCq4)g,2T'ݪ̃} c :3N8Fi\(1+{ёy}cK <~ yQ#k;f2223֪Y8F֡u5mL6aD$o9$T_~괬x1055s@tGW@U!@9@|rq@h}Zv #9''?T[< W`mD 7Jh&ro승'Ѱ<)0l\R(\dazjLビ搿N ;i-#R0*ܶPݹcYy$*҇r & [qOn6> rO {;FKַ-0HDӨ0@3Utm4^\c 3ں@ LzU\s|3MG֬\њnh;4fHI# }*2h4i4HZZajB޴ aGJ*0=Ph2x`*mXIܦõ'PsQ20’33^)a_^at줸uԦ(m'=KV,j'ܼL7g?Z#vo҃hPZUx~嶐igbSsVM?:ȓ+ Od@LEsFyyRq* 0ߕ;q@8# }(MK1,_/83:C<Ҧ:b= ?O*-"SZ1T7`2A)L7޷cPY[ eo1bۡj cfǛX?*3ؑ#տz;T;h ,X}$o[A=}EjQEJRc7, $OaI%(?Ʒ))Y<4%5 0vjK X y%]$$dB[z%,%1LbƱ*aQM^%NRqE=S"<vh 'l8槵/X8aQ I=)ek:*;<E;ˏ:bSxǩ7T[='baK}ydrԙVM͍Z`HHYqd0>>r NJ}=EN&W7 m}ҴZ ӽDf麆3i_Vîsg(E$TaR Ȼ KΔ/=c'ҋ.`>@NⰭ)'JO1QiĂSꟊSoUcC\P+uői|G3U@ |؏B?ݙƙQ=^@~y 1#,u3F=(T?Ȧaie~@ !o<ѓh٣6'⋁Ge>7~JAfjg>}:WO૸wHк>󤑉N1E_sKր RaUQ<})Cb[}[VW;1gN*:f gLTl4ǫ'GU؛ܛ4MDГS; -GJnUloLnpO֖ب ܽF+f&2Hجn};Jv7FG$i1(9}@J/#%}Ǩɏ FAah|pڻ Bn$z汕7sh{0j񣕅8.ڻh;)1Wy ?&\Gz1V4R_&ٿ6ٗf|QzGAf:203RA]RCE5JcҘ4UARMQ< . D0Qa Q#OZ|caI/~њgl{9P1jIThTsަUȨsS$c4:{-|GB_w[ U&R2bc⠁̨LRZ4 Uko,cw ~~94YW^ %GFg>Y&aǧֶ-meov$r4Amn+8*^dclr^A73X[.;r+B^;Y*: juېi;L8Kt?TQkv`R(9#8? ؾ&Ҭ?~UEmShyџjXgeZ,:}j9XbkKS>T6x3S1 a̍=ǢS#55[CV?U6p5-8G+24ES4r0m~?,UxfBz{dahƌ͛=+1}\?'_&-[\p?IKPwRƋƏzPeM3q4~AtO<k_* &= J\04C/#֥q6Ru)|/N7vS&zhXնy4>yf2vrRjlc  ͻ 旧Ҋ !#}j@WũPS*j`0QR4#or˞t|_?q:52 zfhJTHğ-Cf\ʏ,G8 o/²#n2+JDI܋EtosY?Z$V}}K]dKW~n!!!( 28P@#<1iSxWG& & arϹ.W8n?_Xx-0}Ոؓ zvRoxnl~ssQEE8ŒԞwXn5eKIbXBrOֻ )*wЊ˟fk;p ( 9ߩH|}1Ɍ+h$o~n:ET >xLC#@bg.Gqr=«`쿝}?t8q9[{hG dw'(so!R""grx Oq^wKWE&v"rDkSumm|]C,ĭ"[vc\Zѣql<NAa+ Qu] 9ς?V!n(((fHC5e,A[V9\dqpz:m|ȥWPq?\cǵ7LMI{ZV%-Gn<5zLF,8vAcO&0!Jڠ5xCNå8C»!/R7Tw}\FC,##Қ> !͵5(,taQ'ZLBk''ϛ嫇xoJOs NӴ;ө)jYH1LojA֚8 c`RZ: {ݚ ѫ7ԭݲњ ^-Zydg.`QX=ҹWtpW:䀕t^qOZG2Gkެ}N+LVNAϿ?O!\;DQZsLڲc+f<ɿnb FEh30? ?ɏC&4t7+2$k_M|??A|zwܓE%}hN++XB+JAdRT`c9PPQEQEU}@n~b۟N(-/A|U{wן^*%ESQU丑 ͻm^"H1: |EZ Ŋ '++?iisoma Du$W Q<]L"@YN;\.kc16]`ȘyW2̙1J?ν ᮨS:|{04۷ko]SBSmki 7(mfC>V؄5<$iZ#M/?W\ )]cjd/_q*RԌ??)+Cﳛ^8uT85v Si"4kt4 ҤsL$_z"-F0)fT XR'*7Ԧz_c0ix旟k=k֪wq޽pC*[3@ڸS#gh`;ku.4?֤R;cO,d20$P:Y ,av'MnmEAh83-֤oGkb=&m#?Jܻ@-g+tՐ쾻J_j3y/w㕤Ѐ1RƑ1V,pF=sWџ jĆ__3O1A?½7rKO5\lLEw!Q:})ۗѽ(p?'_ΘOGO΋o.:8b}:d6, {&V,M c\Vr3SN6;B5`\zfKvIEF$A/9SUa\.Iy x)cҳwlV?7q =`)Jl=|#gZJiV]HTZu4PNIRFR3_9?*O_~8ant4x'<*D'XpB`{Է7lsn5\m:湽sA[GŽͣmu旅s(ބQB){HCYrl{;_}J戋s3XW>"!ѱ4Mnn#12UIw9Ǚ95Ũ).L#[YYđ%ʈĀI5^;4?GxfIVlʹ @$ af>dzc⎇`XhV6yappIOcJ.5}bڍ > !TS{גQ`2e@ Qogy4}zR-Yunʬe ;#? TV%SN=SJG™ Nr{f ,{0d>!>ϝf7[ #n_+F#+FRSm,اlm*A;`S$zCAWdD& =1QoSXQ+⥆oqw-jlmqYD62 a c^fwNV%8%,:v%$F$x+31\G+qӼSjZ*fr=9+-T]·Or*djw˅`1sjMټWn/R$( BD[o ב,]jRwW=ХR Ujz5M;KWQ5Ar*r#N[簮RDͻ.iP*qsy`j7rR(K 2ʤ8I`Um2dk34w2F?t[>F~n:fw?2Z\pj/w*7*F\ԑ?##6QQvqSR="K%nQs3tFuc4'?H1(iVa^Es)lJXDs*GH͞'3(X}#__2ȨS\ݸ29+Gz=vZǙ4H)b!)T!:i]Y58lK(O"L.F.9'վ j\0U ickLwn54?ǯ<ۥQocEJ˹I-9&}^E=s?tZMϮ> K4kt[ ׎w6 p ױ˥.ɨ]B¡$$)㌐9Z3kkye3F-X@܀%3wk{6X0d [$A 2ܗ$;vWVKhҍ@މ +"Uvy)\M+R91ܥʞI4Tg$ @5- [ -) '8#ӎv曯)7Y8̰2cFGqˉ9]Ԍ]/(v.  ~x^xuK_Q[}KL[6 ) &Ӎǐ J=GPҵk8#5.>T24qW@mls](r96U&$Z2thj ed'$F39szc_ e[ !S11 zu?jy j㢱DÎC`5-B."yx%A`:zG#RQNw՞M{W'R iTdG&<*Τm;,jq-LeK'H!vpppz|'w mn$*P *H&ob񗇮&N6 Ld]045v"r@嶙5J-+ȼHJz`tDp؅zO\Ť~tj4MG]C=R[-2Я@mDL$u) 4SAQM(|;qN)Jm'h=43*"i \J]rM'bxM?CZ,b#O54G#6^8Ixq"zsxUKbcNZWE޹O;cSӥD*Tj2R cD*APQG涢?O(ֵ8L^?XV8IeH;Sǁ֮Z' 7c>)f/8¸oy#CMg_|r_ɔJBDđ0 k3B8+((n@ΊTx=k^n&+(fyp6p0sJ!;2{z[e+YGӔu!;zpLT,8@#V+glC7ƞqҖidb{:gӟltYE,$'b܁Η2O$PI%E@%Dl'n޽*@X^Xq?*K+7NBOO$e.H1=p d+ZP'Ď}W-ñDe-~S۶E\F܊=uG|FG5$1yJp_-mqk)˛g|);dsYgA$Rj[or=3zҁ>Ƞ`fAֲrLV҆eI\=y9泌}UM]' MU5%(0oVt"EGZM/ ^N+Qum㳼_DnTU\6HOc Ҭm8Ts³*FN[RŖl(,{W1B(^A_k-jUFxW{6ѹ qu],Z.$jȌ2&bi'#BUzgs`I}as.\$.Ҧ67@lboe]7G\~ߨXipBAr{ N>ݏ١fi@b؀ɪVށ_\*~TNAGN1ڷa+yv33IC}>Pt[S#e&?Q:27c23YcF " KA JzҮM·Q0jWQİ -m3vZMt +;p =TfYmt@6qv$vҳu)Dr"$=}{Nx{'}¦#iݣsG9Hȟִ*;j $3w?JwV"sЕj4b :.89C9riddl*89NM{W jzMw>,JN@Ñ}Nkռ# n ň8H-dqtԊ2}/YUG5)o4F"LܬA]7d}M#O<[Akv9>O0Z`Uyst]V,gh[W]|5OHコwTuj] T~|jЀQcb`kCBA1 KӦg o3aKmp8I TlK nw?G]&80bH#1nR.7`]2U Z[ w,1''&hRU/ U$J/WDT%$Q.} sI^W2%Xwy{ {bˉSl;n?Hէ58/nKg8$b s*N3GI#d&H'a9ם鱴/ $/rzÍ}S^5MHAĥ6@95(;m$ gOš1VA :t1\Ȉrv(80wGx@B%Drq*^JO"p_-v-m~.U%AYHIYG$M'ʪz[׍M)^Ftk䘳OOSKKG6;K;J.T#Vlz*+\ :wr7V'OXzPwm͓\08|`RU̴us8IUjy,q! t +ver$e6N1#?EqZ@U`1lF 5UY%Da)X76tٰ1ZszHcTeN-NBͻ*3FOz#9>fokelX{V1׮ŤK+g~r)s>qȌ>!SQcgyn[|ѻ/ofm8$~$IYU."D!ddx ID?αfɔ;d}qܞ֟dۗl1 AK?Zd~_s)9ȍO;zq>ӧJ̚!(n$ĜXAߜsU RDud~jݶ}@@튱i3L"ΝFC6Jw~<{V0rѫUq}^G>э;1onà4:lrі(!'gW5GIV$DOȵNYd sT]ZnR0w#4Lr .JL}:խ.Đoo)dgu9 yM£JQR[-KB 3qY^JǍȠ;uqq,3U\}sX(hKSYNEw O' V}esq+_ x[E+VOAr@5E'zukuI YDLX"P@b\A8Ĩ?ZbksJXAp=*3bx'5^bzb!? `c4?})1sL'Yo*9&1|~q3ooPiF>˅#<Y&_ir6ռo¦tg;S@fohms2x8? U"pzkV<%F .[wi%C@,P ^>7tm8˅ǵK3F͘лr05aysQ5z9Bo\T:ƦmnF4w`˹R}xZ2}4K n~y-"x/Ւtpq\s''KC|*i0Gs'TFl{\!:#'_Ft~&U%*'|++5)l^:vP %ەj9Kd?Biatɟl׭18&]OVO‘lE^X t-չH@@YjqSTzOe1%pG{W4[u8.-I809=Z>K#6˂ ?\=cLrf "Qץ(1s{ŃH짂*:t5oVTe҆Ts+ZY# g?`Jef!Q]ʩjKtڇ{rq{=+cFrSWqV cAqaƗ@>TC(>IudsRYHZjĪ$ ?X"ya*t*9 +\6.J\ٙbpp控K|T/kkF!13gҺ'㶍,-fNpb?5wnJұukh ٹ6(8ץ¤Z, 9+}exC6A6{+#5 L3Nk/~ ebDehL g9S|M> ^HnIMQ-49c #醉pIcr3[H?SUCl)P5VvZ1}Y5P@3_'8+n飞I%z~]jI;s({ tMr M(r8giJ*3bGS61ӑ\ƭUEfXC g!BX{VeϋY@`Z|ISR2IE5P=b/LV{ TRk(e6 1*F+:H tcܠjk* amŤ1sq f۪+A(SN39G;!`H:J\ 7#WH_XPmܺ46[[E InI'l2)؟sY H\/^vorWMQ (2}rRC|\ޤg5>qH1#ܚ<#׿<ћh͞oX>eL1?Jm/|rȻQ:ӷ]+ +mm# ʥO_7Qʻ/SCs$~T\, |<djؙ2,P3 XhTf/Ԓ{sKW)i^'iHs߈ !|xD[@qoǵGc&k$19yl_~WNH*``mVN<ץA ' ogC1胿;yTUƯ- ̋{c"mXFEflw# yzy$!;Tue!\:=8: Լ(#|¼Wu~G\_5;ԊX!"G )H +Xڅ}fX˔0;*;i[QM+SEA$*|~/GOJ̽}[،*_Һ z#{4#y{r\ׂ}*(ncuSez]TUUWJ3tᗆ4?ڥƻ`/%#Gip0H_ⶁxzI]OKE2vmv;5ke+[%S<*Y@r9=VYҿ.Bꀂ ^)a=֯oUbuN߆W xb-gqq4st,HH E}3Nn71&@[<{Uk;k-t]vCʱHӲe1\d6T.GӰ759=p& ˜9:*Jhtn?*-c8gLjC$.n|xo-Ǟjp|2o&J-JĸXdv#JM#q`zt-QT,PZE\ UGP:E)lƷBu$=*7n[U܅?7ʊ(y*@T&y9ȪD$?x[h ŸG3R\ "T,FŃ4*F228?*~s[˕`k#&?3= OBAdg#Tjѧbn;vFfv:R+rbgkLG?!ӓX3HK6 ` ¬NZIKI'Prkrrf*3єۭMt[äyګ!0('Xĩ`fiϦNs\Fum&+!{ xd$oQlc[6#i ߷uAk4ry9!_:{U9Cs$wd@=N}kvuOĶhs\,vYs2k3X 7P@AsZni"$p$9Սnynf1s)8׌u5Xuw.jKOޑo)`02M❰cZjOq mݾU9FbI>UA>lH݀"Jkf 9Pk43""F 'xcnC78?3 H$53(8#V 1 $1`F?9Ζ(9B#=?[?1Cp՗ }pj1,BB^;Sl `w?*ӇcUZIh6ǿX쁾z$/ 䚬+xnR3|0;f\yqc)\^o#Y"7F:ZK ĵп8k۫'bv 4%0y60:i/|pCp1d}ktf`M{hw\@˚kv6 >ӽRI<'|0%9PB8ΛETr Y,H)YP#5Nv8XH#^єtc V :ـ@O?@*i 01ATdnL1O(yooBRl:8]@;˖T9=N)>ϨLθXFsr*d #C`@bG SPb1n1WYH/"H>SPNDm.x|Cz2ps9 ̫(5j0{d*ԣ# 3^s-g@?xGzr r\\`㷶jQNIiu%m1S@rLLUuXdǰɩ7'jBqS? vd{xt<[#h'9U*\=+rGE%s)IQA3Shs) 9*PoqK >E0F8<)Üq8?օFJ'*Te@#+9Z:yUIVcV,\;Y閌ldj #$de~ԞSX۾s9?<)pv5$yg 88"K6EIi¼NKF8b1 }jvAoo!6Y 0 f'0zzd;U;|C MCGѨ4!R+˕,=@gȩ٥d~<ۭV׋wF@ ~ M-ؚWJ2>Fo\gEs.W/Ē("Q2ro2=*{_}e%=0o$h$ Hf5! Ux MJ/eS)gd  g'= ]"D 1bL p`fH ' 0=6L?f UZ4$ [yXbi3/'==t'@~z&Rs|\4[ Ag)i|*l0<?N?,xHyܪ7_3{Tw9<z~kܳgm˄Z"]j]#\L"ˏ"EyP|3ߜsұDe/ 8'5nՒ*fz ʒn?{0bskCBv{^`9 񤹒y;V6T 70@1anvGO>-J)XDQy62v(_Îzwr3KE7r"`;ڊ{sQOtAo2r~z3ZmA##V#2#  TA(=N hxq?_OQ)]ͱ61c֫Tw\ Ğ)2fO""'1-ȯl^'ʜa04^.-a| wm{MY$ vA!oC-ġ*@7Sdj ?Kzkw2dY0F@Xe t=Hs2 OJĎ|gՂώvVM=J$xN{Ui,觍>~UR…LSd\XuQUkRl,Um&+ӑS#rA+KJWRѝPHǽ&Ɛ;u$㍕!x8#*,=Qk|2=[ nciBysя 9V=jO/ H0\6V[A;ܻf/pL=aPf=©IH^Ds xx5жBbԭ#oAF~Kպr~&5N- 4g##5^(0<©,!y^[A܊]2=؍`xn c򬧡k'6QIfQ[ \OpC'v$!T&91IbE^[';q"tXIBRWڌe-OqU{E9i\ '`g'ѵFA7K1K䔵 ZnٺE}{ƥfL+ $|{?ZemrO+j >8RcV~1N슕aA[%HUVPلc眃 sfp me#-Ey>Θe|5KS$ߏ(+NqC*a%S9", }tVWB7n1$`9mMeo~?1I6Љ 2Ԏ}8$ޤ;`<\ 10@OԓՇ-F!A tB}2 Lϗ&jĂ3ަr(*Nj]<ǐhOOJqbBC{^T{#G]3F50Lc.#ƘMi%PVa u֪^EuO\6`J#m݉@"MA֡CO$?֮dOsT7Z"1)T.qT2qJb!$<2/>2L# 3Tq(X]AQ'V9sTv+@1<ӧJrӏL֌^0Q <⋊Fr)r\fgqrcU˷xkd *DrrxqUab78*2=j儌D"OyIh iwpOA~棻@7F¤%LAFnU;J%rf$vӅe_L5;6:P ;ϗ4]HqYkF\j>tã#OE9Mf fd|ebe\zN]q&XUYI?CUf%R䕒 ,qȩe?!47%@5Q$8*kciMiݏA}yUʴSl 1w&~]*-,%P9c?S^yY h(6:B-&۲i/R`?-۸DZhɧ&y_"H%? kJh)5{9"92|ywC 3 )8L[#Jj.yw3uVgEgfS';jY[X_x_U##/;f+LZul*-m될ϵ!u0>X1Zd坘 o5i0^:zP}U`F1R\ё9MOh4@UbFG5e+B.N3RCm/i7HKt*QsMwĤ s*}ntK&Y.1^DCǶl\}Q޳m`]+5.c$9z j=J{^3FxF08c:CeXg vܜWAheܴ('H{O8ݑ8qXeۆ#Zz# t\2n`V2Ayϩb+Jz_2R(*+g'Ԍ 98MhHdW=}j&Nzu8!R"RyJ;JvM"+Tl̜{?Od;m56~S~U9=8\›wiҡ@R96L]amJGӽ\BB<犵 (Lԡw,@RC`ӊaȏUaۊ甭&lNqAON\9*1zLѢSF>J-=@A#`FP}9a׊Ҧ$@[=xK8Ԭ@p>1X^ݹy8;<]# QIq/SiI =)N}* S&<"J6r0GQH28=iGPxa3 `:zԝGP41ߧjnЇbF#)8ScܧSs@%ʜ QpU:8|4\ <Ҕܸ槕64sCN+2wCIjG8晷M0mԜ:Tkv(2r2j"N;UxTNGLQpV7Rc08# i+W9t Pa]S '{sA#y4vɭHOJǴܜ#\TAkZ+H00>TD`9 ` t1(<.#JzilJA .` }dE]1eQ}BӜGVBsWB82Dˡ⋈"UtM ҭ2? |ϭ dl/#Њ#֚Wv\e]]XqڥqeHCc&Ncq4v= ;[ޭjD Ew ~]F+qW$['sϥ2e 71py=6RI=*uW$qNx{)ϹÞژkQLG ϭ9g57 <x&ei8㊁>R[hEK qsϽR`£,=E>59#.1}iQp%+#j0;Ҫ{r)0 t7pE!vQJs׊k8Sg"evүq35W=LeTz 358u8 =2)'XavRG\wB$Vč6jO9e`F98REǞI q<+ 1XI劅W$^=;Q2# PX>œQ 1Xx>$8MS})rvqHi :sP {=袵%=?lQEf) nZOqqE:6gw7RcDqVǠQI"tcR=3QEH:9?xPR@` Dz(d`}qIp;QE!/Oʚ>QMUf<}3EENaRzKy~tQB$rD5SBW#rE"s٩GZ(%g?@i&9obG~8hQ*P&{ g( (ZQLD5g8Fz=("?:T2E ?mojo-magick-0.5.6/test/test_helper.rb0000644000175000017500000000024612542772650017115 0ustar sophiesophierequire 'test/unit' require File::expand_path(File::join(File::dirname(__FILE__), '..', 'init')) require 'fileutils' require 'tempfile' require 'rspec/expectations' mojo-magick-0.5.6/test/font_test.rb0000644000175000017500000000130112542772650016575 0ustar sophiesophie require File::join(File::dirname(__FILE__), 'test_helper') IDENTIFY_FONT_RESPONSE =< "Zapfino", :weight => 400) assert_equal f.name, 'Zapfino' assert_equal f.valid?, true assert_equal f.weight, 400 end end mojo-magick-0.5.6/test/fonts_test.rb0000644000175000017500000000045112542772650016765 0ustar sophiesophierequire File::join(File::dirname(__FILE__), 'test_helper') class FontsTest < MiniTest::Unit::TestCase def test_get_fonts fonts = MojoMagick::get_fonts assert fonts.is_a? Array assert fonts.length > 1 assert fonts.first.name assert (fonts.first.name.is_a? String) end end mojo-magick-0.5.6/test/opt_builder_test.rb0000644000175000017500000000746712542772650020162 0ustar sophiesophierequire File::join(File::dirname(__FILE__), 'test_helper') class MojoMagickOptBuilderTest < MiniTest::Unit::TestCase # These tests make the assumption that if we call #raw_command with the # correct strings, ImageMagick itself will operate correctly. We're only # verifying that the option builder produces the correct strings def setup @builder = MojoMagick::OptBuilder.new end def test_annotate @builder.annotate 'blah' assert_equal '-annotate 0 blah', @builder.to_s end def test_annotate_with_escapeable_string @builder.annotate 'it\'s' assert_equal '-annotate 0 "it\'s"', @builder.to_s end def test_annotate_with_full_args @builder.annotate '5 it\'s' assert_equal '-annotate 5 "it\'s"', @builder.to_s end def test_option_builder_with_blocks # Passing in basic commands produces a string b = MojoMagick::OptBuilder.new b.image_block do b.background 'red' end b.image_block do b.background 'blue' end assert_equal '\( -background red \) \( -background blue \)', b.to_s end def test_option_builder_with_hex_colors b = MojoMagick::OptBuilder.new b.background '#000000' assert_equal '-background "#000000"', b.to_s end def test_option_builder # Passing in basic commands produces a string b = MojoMagick::OptBuilder.new b.strip b.repage assert_equal '-strip -repage', b.to_s # Chaining commands works b = MojoMagick::OptBuilder.new.strip.repage assert_equal '-strip -repage', b.to_s # Bang (!) indicates the plus version of commands b = MojoMagick::OptBuilder.new b.repage b.repage! assert_equal '-repage +repage', b.to_s # Accepts raw data as-is b = MojoMagick::OptBuilder.new b.opt1 b << 'a ! b !' b.opt2 assert_equal '-opt1 a ! b ! -opt2', b.to_s # Treats an array of raw data as different arguments b = MojoMagick::OptBuilder.new b << ['leave this data','alone'] assert_equal 'leave this data alone', b.to_s # String includes command arguments b = MojoMagick::OptBuilder.new b.extent '256x256+0+0' b.crop '64x64' assert_equal '-extent 256x256+0+0 -crop 64x64', b.to_s # Arguments are quoted (doublequote) if appropriate b = MojoMagick::OptBuilder.new b.comment 'white space' b.comment 'w&b' b.crop '6x6^' assert_equal '-comment "white space" -comment "w&b" -crop "6x6^"', b.to_s # Existing doublequotes are escaped b = MojoMagick::OptBuilder.new b.comment 'Fred "Woot" Rook' assert_equal '-comment "Fred \"Woot\" Rook"', b.to_s # Multi-argument commands should not be quoted together b = MojoMagick::OptBuilder.new b.set 'comment', 'the "best" comment' assert_equal '-set comment "the \"best\" comment"', b.to_s # File and files are helper methods b = MojoMagick::OptBuilder.new b.files 'source.jpg', 'source2.jpg' b.append b.crop '64x64' b.file 'dest%d.jpg' assert_equal 'source.jpg source2.jpg -append -crop 64x64 dest%d.jpg', b.to_s # Files are quoted (doublequote) if appropriate b = MojoMagick::OptBuilder.new b.file 'probably on windows.jpg' assert_equal '"probably on windows.jpg"', b.to_s # Blob is a shortcut for the #tempfile helper method b = MojoMagick::OptBuilder.new b.blob 'binary data' filename = b.to_s File.open(filename, 'rb') do |f| assert_equal 'binary data', f.read end #label for text should use 'label:"the string"' if specified [[ 'mylabel', 'mylabel' ], [ 'my " label', '"my \" label"' ], [ 'Rock it, cuz i said so!', '"Rock it, cuz i said so!"'], [ "it's like this", '"it\'s like this"'], [ '#$%^&*', '"#$%^&*"']].each do |labels| b = MojoMagick::OptBuilder.new b.label labels[0] assert_equal "label:#{labels[1]}", b.to_s end end end mojo-magick-0.5.6/test/resource_limits_test.rb0000644000175000017500000000267112542772650021052 0ustar sophiesophierequire File::join(File::dirname(__FILE__), 'test_helper') class ResourceLimitsTest < MiniTest::Unit::TestCase def setup @orig_limits = MojoMagick::get_default_limits end def test_set_limits # set area to 32mb limit MojoMagick::set_limits(:area => '32mb') new_limits = MojoMagick::get_current_limits assert_equal '32mb', new_limits[:area].downcase end def test_get_limits assert(@orig_limits.size >= 7) end def test_resource_limits orig_limits_test = @orig_limits.dup orig_limits_test.delete_if do |resource, value| assert [:throttle, :area, :map, :disk, :memory, :file, :thread, :time].include?(resource), "Found unexpected resource #{resource}" true end assert_equal 0, orig_limits_test.size end def test_get_current_limits # remove limits on area MojoMagick::remove_limits(:area) new_limits = MojoMagick::get_current_limits assert_equal @orig_limits[:area], new_limits[:area] end def test_set_limits # set memory to 64 mb, disk to 0 and MojoMagick::set_limits(:memory => '64mb', :disk => '0b') new_limits = MojoMagick::get_current_limits(:show_actual_values => true) assert_equal 61, new_limits[:memory] assert_equal 0, new_limits[:disk] end def test_unset_limits # return to original/default limit values MojoMagick::unset_limits new_limits = MojoMagick::get_current_limits assert_equal @orig_limits, new_limits end end mojo-magick-0.5.6/test/parser_test.rb0000644000175000017500000000121212542772650017124 0ustar sophiesophierequire File::join(File::dirname(__FILE__), 'test_helper') IDENTIFY_FONT_RESPONSE =<100, :height=>100}) assert_equal size_test, retval assert_equal orig_image_size, File::size(@test_image) assert_equal retval, size_test new_dimensions = MojoMagick::get_image_size(size_test) assert_equal 100, new_dimensions[:height] assert_equal 67, new_dimensions[:width] # we should be able to resize image right over itself retval = MojoMagick::resize(@test_image, @test_image, {:width=>100, :height=>100}) assert_equal @test_image, retval refute_equal orig_image_size, File::size(@test_image) new_dimensions = MojoMagick::get_image_size(@test_image) assert_equal 100, new_dimensions[:height] assert_equal 67, new_dimensions[:width] end def test_image_resize_with_percentage reset_images original_size = MojoMagick::get_image_size(@test_image) retval = MojoMagick::resize(@test_image, @test_image, {:percent => 50}) assert_equal @test_image, retval new_dimensions = MojoMagick::get_image_size(@test_image) [:height, :width].each do |dim| assert_equal (original_size[dim]/2.0).ceil, new_dimensions[dim] end end def test_shrink_with_big_dimensions # image shouldn't resize if we specify very large dimensions and specify "shrink_only" reset_images size_test_temp = Tempfile::new('mojo_test') size_test = size_test_temp.path retval = MojoMagick::shrink(@test_image, size_test, {:width=>1000, :height=>1000}) assert_equal size_test, retval new_dimensions = MojoMagick::get_image_size(@test_image) assert_equal 500, new_dimensions[:height] assert_equal 333, new_dimensions[:width] end def test_shrink reset_images # image should resize if we specify small dimensions and shrink_only retval = MojoMagick::shrink(@test_image, @test_image, {:width=>1000, :height=>100}) assert_equal @test_image, retval new_dimensions = MojoMagick::get_image_size(@test_image) assert_equal 100, new_dimensions[:height] assert_equal 67, new_dimensions[:width] end def test_resize_with_shrink_only_options reset_images # image should resize if we specify small dimensions and shrink_only retval = MojoMagick::resize(@test_image, @test_image, {:shrink_only => true, :width=>400, :height=>400}) assert_equal @test_image, retval new_dimensions = MojoMagick::get_image_size(@test_image) assert_equal 400, new_dimensions[:height] assert_equal 266, new_dimensions[:width] end def test_expand_with_small_dim # image shouldn't resize if we specify small dimensions and expand_only reset_images orig_image_size = File::size(@test_image) retval = MojoMagick::expand(@test_image, @test_image, {:width=>10, :height=>10}) assert_equal @test_image, retval new_dimensions = MojoMagick::get_image_size(@test_image) assert_equal 500, new_dimensions[:height] assert_equal 333, new_dimensions[:width] end def test_expand reset_images # image should resize if we specify large dimensions and expand_only retval = MojoMagick::expand(@test_image, @test_image, {:width=>1000, :height=>1000}) assert_equal @test_image, retval new_dimensions = MojoMagick::get_image_size(@test_image) assert_equal 1000, new_dimensions[:height] assert_equal 666, new_dimensions[:width] end def test_invalid_images # test bad images bad_image = File::join(@working_path, 'not_an_image.jpg') zero_image = File::join(@working_path, 'zero_byte_image.jpg') assert_raises(MojoMagick::MojoFailed) {MojoMagick::get_image_size(bad_image)} assert_raises(MojoMagick::MojoFailed) {MojoMagick::get_image_size(zero_image)} assert_raises(MojoMagick::MojoFailed) {MojoMagick::get_image_size('/file_does_not_exist_here_ok.jpg')} end def test_resize_with_fill reset_images @test_image = File::join(@working_path, '5742.jpg') MojoMagick::resize(@test_image, @test_image, {:fill => true, :width => 100, :height => 100}) dim = MojoMagick::get_image_size(@test_image) assert_equal 100, dim[:width] assert_equal 150, dim[:height] end def test_resize_with_fill_and_crop reset_images @test_image = File::join(@working_path, '5742.jpg') MojoMagick::resize(@test_image, @test_image, {:fill => true, :crop => true, :width => 150, :height => 120}) dim = MojoMagick::get_image_size(@test_image) assert_equal 150, dim[:width] assert_equal 120, dim[:height] end def test_tempfile # Create a tempfile and return the path filename = MojoMagick::tempfile('binary data') File.open(filename, 'rb') do |f| assert_equal f.read, 'binary data' end end def test_label reset_images out_image = File::join(@working_path, 'label_test.png') MojoMagick::convert do |c| c.label 'rock the house' c.file out_image end end def test_label_with_quote reset_images out_image = File::join(@working_path, 'label_test.png') MojoMagick::convert do |c| c.label 'rock "the house' c.file out_image end end def test_label_with_apostrophe reset_images out_image = File::join(@working_path, 'label_test.png') MojoMagick::convert do |c| c.label 'rock \'the house' c.file out_image end end def test_label_with_quotes reset_images out_image = File::join(@working_path, 'label_test.png') MojoMagick::convert do |c| c.label 'this is "it!"' c.file out_image end end def test_bad_command begin MojoMagick::convert do |c| c.unknown_option 'fail' c.file 'boogabooga.whatever' end rescue MojoMagick::MojoFailed => ex assert ex.message.include?('unrecognized option'), "Unable to find ImageMagick commandline error in the message" assert ex.message.include?('convert.c/ConvertImageCommand'), "Unable to find ImageMagick commandline error in the message" end end def test_blob reset_images # RGB8 test data = (16.times.map { [(rand > 0.5) ? 0 : 255]*3 }).flatten bdata = data.pack 'C'*data.size out = 'out.png' MojoMagick::convert(nil, "png:#{out}") do |c| c.blob bdata, :format => :rgb, :depth => 8, :size => '4x4' end r = MojoMagick::get_image_size(out) assert r[:height] == 4 assert r[:width] == 4 end def test_command_helpers reset_images test_image = File::join(@working_path, '5742.jpg') out_image = File::join(@working_path, 'out1.jpg') # Simple convert test MojoMagick::convert do |c| c.file test_image c.crop '92x64+0+0' c.repage! c.file out_image end retval = MojoMagick::get_image_size(out_image) assert_equal 92, retval[:width] assert_equal 64, retval[:height] # Simple mogrify test MojoMagick::mogrify do |m| m.crop '32x32+0+0' m.repage! m.file out_image end retval = MojoMagick::get_image_size(out_image) assert_equal 32, retval[:width] assert_equal 32, retval[:height] # Convert test, using file shortcuts MojoMagick::convert(test_image, out_image) do |c| c.crop '100x100+0+0' c.repage! end retval = MojoMagick::get_image_size(out_image) assert_equal 100, retval[:width] assert_equal 100, retval[:height] # Mogrify test, using file shortcut MojoMagick::mogrify(out_image) { |m| m.shave('25x25').repage! } retval = MojoMagick::get_image_size(out_image) assert_equal 50, retval[:width] assert_equal 50, retval[:height] # RGB8 test bdata = 'aaaaaabbbbbbccc' out = 'out.png' MojoMagick::convert do |c| c.blob bdata, :format => :rgb, :depth => 8, :size => '5x1' c.file out end r = MojoMagick::get_image_size(out) assert r[:height] == 1 assert r[:width] == 5 bdata = '1111222233334444' out = 'out.png' MojoMagick::convert do |c| c.blob bdata, :format => :rgba, :depth => 8, :size => '4x1' c.file out end r = MojoMagick::get_image_size(out) assert r[:height] == 1 assert r[:width] == 4 end end mojo-magick-0.5.6/.gitignore0000644000175000017500000000012512542772650015257 0ustar sophiesophie*~ test/fixtures/tmp fixtures/tmp coverage/ .bundle/ .\#* \#* out.png out.html *.gem mojo-magick-0.5.6/Gemfile0000644000175000017500000000004712542772650014565 0ustar sophiesophiesource 'https://rubygems.org' gemspec mojo-magick-0.5.6/metadata.yml0000644000175000017500000000663212542772650015603 0ustar sophiesophie--- !ruby/object:Gem::Specification name: mojo_magick version: !ruby/object:Gem::Version version: 0.5.6 platform: ruby authors: - Steve Midgley - Elliot Nelson - Jon Rogers autorequire: bindir: bin cert_chain: [] date: 2015-05-31 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: simplecov requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rspec-expectations requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' description: Simple Ruby stateless module interface to imagemagick. email: - science@misuse.org - jon@rcode5.com executables: [] extensions: [] extra_rdoc_files: [] files: - ".gitignore" - ".ruby-version" - Gemfile - Gemfile.lock - LICENSE.txt - README.md - Rakefile - examples/animated_gif.rb - examples/composite.rb - init.rb - lib/image_magick/fonts.rb - lib/image_magick/resource_limits.rb - lib/initializers/hash.rb - lib/mojo_magick.rb - lib/mojo_magick/command_status.rb - lib/mojo_magick/errors.rb - lib/mojo_magick/font.rb - lib/mojo_magick/opt_builder.rb - lib/mojo_magick/util/parser.rb - lib/mojo_magick/version.rb - mojo_magick.gemspec - test/fixtures/5742.jpg - test/fixtures/not_an_image.jpg - test/fixtures/zero_byte_image.jpg - test/font_test.rb - test/fonts_test.rb - test/mojo_magick_test.rb - test/opt_builder_test.rb - test/parser_test.rb - test/resource_limits_test.rb - test/test_helper.rb homepage: http://github.com/rcode5/mojo_magick licenses: - MIT metadata: {} post_install_message: |2+ Thanks for installing MojoMagick - keepin it simple! *** To make this gem work, you need a few binaries! Make sure you've got ImageMagick available. http://imagemagick.org If you plan to build images with text (using the "label" method) you'll need freetype and ghostscript as well. Check out http://www.freetype.org and http://ghostscript.com respectively for installation info. rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: mojo_magick rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: mojo_magick-0.5.6 test_files: - test/fixtures/5742.jpg - test/fixtures/not_an_image.jpg - test/fixtures/zero_byte_image.jpg - test/font_test.rb - test/fonts_test.rb - test/mojo_magick_test.rb - test/opt_builder_test.rb - test/parser_test.rb - test/resource_limits_test.rb - test/test_helper.rb mojo-magick-0.5.6/.ruby-version0000644000175000017500000000000612542772650015732 0ustar sophiesophie2.1.5 mojo-magick-0.5.6/init.rb0000644000175000017500000000012712542772650014561 0ustar sophiesophierequire File::expand_path(File::join(File::dirname(__FILE__), 'lib', 'mojo_magick')) mojo-magick-0.5.6/lib/0000755000175000017500000000000012542772650014037 5ustar sophiesophiemojo-magick-0.5.6/lib/initializers/0000755000175000017500000000000012542772650016545 5ustar sophiesophiemojo-magick-0.5.6/lib/initializers/hash.rb0000644000175000017500000000021412542772650020012 0ustar sophiesophieclass Hash def symbolize_keys! keys.each do |key| self[(key.to_sym rescue key) || key] = delete(key) end self end end mojo-magick-0.5.6/lib/mojo_magick/0000755000175000017500000000000012542772650016316 5ustar sophiesophiemojo-magick-0.5.6/lib/mojo_magick/errors.rb0000644000175000017500000000024312542772650020156 0ustar sophiesophiemodule MojoMagick class MojoMagickException < StandardError; end class MojoError < MojoMagickException; end class MojoFailed < MojoMagickException; end end mojo-magick-0.5.6/lib/mojo_magick/version.rb0000644000175000017500000000005212542772650020325 0ustar sophiesophiemodule MojoMagick VERSION = '0.5.6' end mojo-magick-0.5.6/lib/mojo_magick/font.rb0000644000175000017500000000074012542772650017612 0ustar sophiesophiemodule MojoMagick class Font attr_accessor :name, :family, :style, :stretch, :weight, :glyphs def valid? !(name.nil?) end def initialize(property_hash = {}) property_hash.symbolize_keys! [:name, :family, :style, :stretch, :weight, :glyphs].each do |f| setter = "#{f}=" self.send(setter, property_hash[f]) end end def self.all ImageMagick::Font.all.map{|font_info| Font.new(font_info)} end end end mojo-magick-0.5.6/lib/mojo_magick/command_status.rb0000644000175000017500000000035412542772650021666 0ustar sophiesophiemodule MojoMagick class CommandStatus < Struct.new(:command, :return_value, :error, :system_status) def success? system_status.success? end def exit_code system_status.exitstatus || 'unknown' end end end mojo-magick-0.5.6/lib/mojo_magick/opt_builder.rb0000644000175000017500000000372012542772650021155 0ustar sophiesophie# Option builder used in #convert and #mogrify helpers. module MojoMagick class OptBuilder def initialize @opts = [] end # Add command-line options with no processing def <<(arg) if arg.is_a?(Array) @opts += arg else @opts << arg end self end # Add files to command line, formatted if necessary def file(*args) args.each do |arg| add_formatted arg end self end alias files file def label(*args) @opts << "label:#{quoted_arg(args.join)}" end # annotate takes non-standard args def annotate(*args) @opts << '-annotate' arguments = args.join.split if arguments.length == 1 arguments.unshift '0' end arguments.each do |arg| add_formatted arg end end # Create a temporary file for the given image and add to command line def format(*args) @opts << '-format' args.each do |arg| add_formatted arg end end def blob(*args) data = args[0] opts = args[1] || {} opts.each do |k,v| send(k.to_s,v.to_s) end tmpfile = MojoMagick::tempfile(data, opts) file tmpfile end def image_block(&block) @opts << '\(' yield block @opts << '\)' self end # Generic commands. Arguments will be formatted if necessary def method_missing(command, *args) if command.to_s[-1, 1] == '!' @opts << "+#{command.to_s.chop}" else @opts << "-#{command}" end args.each do |arg| add_formatted arg end self end def to_s @opts.join ' ' end protected def add_formatted(arg) # Quote anything that would cause problems on *nix or windows @opts << quoted_arg(arg) end def quoted_arg(arg) return arg unless arg =~ /[#'<>^|&();` ]/ [ '"', arg.gsub('"', '\"').gsub("'", "\'"), '"'].join end end end mojo-magick-0.5.6/lib/mojo_magick/util/0000755000175000017500000000000012542772650017273 5ustar sophiesophiemojo-magick-0.5.6/lib/mojo_magick/util/parser.rb0000644000175000017500000000416612542772650021123 0ustar sophiesophiemodule MojoMagick module Util class Parser # handle parsing outputs from ImageMagick commands def parse_fonts(raw_fonts) font = nil fonts = {} enumerator = raw_fonts.split(/\n/).each name = nil while (begin; line = enumerator.next; rescue StopIteration; line=nil; end) do line.chomp! line = enumerator.next if line.nil? || line.empty? || (/^\s+$/ =~ line) if m = /^\s*Font:\s+(.*)$/.match(line) name = m[1].strip fonts[name] = {:name => name} else key_val = line.split(/:/).map(&:strip) k = key_val[0].downcase.to_sym v = key_val[1] if k && name fonts[name][k] = key_val[1] end end end fonts.values.map{|f| MojoMagick::Font.new f} end def parse_limits(raw_limits) row_limits = raw_limits.split("\n") header = row_limits[0].chomp data = row_limits[2].chomp resources = header.strip.split limits = data.strip.split actual_values = {} readable_values = {} resources.each_index do |i| resource = resources[i].downcase.to_sym scale = limits[i].match(%r{[a-z]+$}) || [] value = limits[i].match(%r{^[0-9]+}) unscaled_value = value ? value[0].to_i : -1 case scale[0] when 'eb' scaled_value = unscaled_value * (2 ** 60) when 'pb' scaled_value = unscaled_value * (2 ** 50) when 'tb' scaled_value = unscaled_value * (2 ** 40) when 'gb' scaled_value = unscaled_value * (2 ** 30) when 'mb' scaled_value = unscaled_value * (2 ** 20) when 'kb' scaled_value = unscaled_value * (2 ** 10) when 'b' scaled_value = unscaled_value else scaled_value = unscaled_value end actual_values[resource] = scaled_value readable_values[resource] = limits[i] end [actual_values, readable_values] end end end end mojo-magick-0.5.6/lib/image_magick/0000755000175000017500000000000012542772650016434 5ustar sophiesophiemojo-magick-0.5.6/lib/image_magick/resource_limits.rb0000644000175000017500000000666712542772650022210 0ustar sophiesophie# This module provides some mix-in methods to permit resource limitation commands in MojoMagick module ImageMagick module ResourceLimits @@resource_limits = {} # controls limits on memory and other resources for imagemagick. # possible values for type can include: # Area, Disk, File, Map, or Memory # value is byte size for everything but Disk, where it's number of files # type can be string or symbol. # Just limiting Memory will not solve problems with imagemagick going out of # control with resource consumption on certain bad files. You have to set disk, # area and map limits too. Read up on imagemagick website for more. # Different options have different units # DISK: N GB # AREA, MAP, MEMORY: N MB # FILE: N num file handles # Examples: # # set disk to 5 gigabytes limit # MiniMagick::Image::set_limit(:disk => 5) # # set memory to 32mb, map to 64mb and disk to 0 # MiniMagick::Image::set_limit(:memory => 32, 'map' => 64, 'disk' => 0) def set_limits(options) mem_fix = 1 options.each do |resource, value| @@resource_limits[resource.to_s.downcase.to_sym] = value.to_s end end # remove a limit def remove_limits(*options) mem_fix = 1 @@resource_limits.delete_if do |resource, value| idx = options.index(resource) resource == options.values_at(idx)[0].to_s.downcase.to_sym if idx end end # remove limits from resources def unset_limits(options = {}) mem_fix = 1 @@resource_limits = {} if options[:unset_env] ENV["MAGICK_AREA_LIMIT"]=nil ENV["MAGICK_MAP_LIMIT"]=nil ENV["MAGICK_MEMORY_LIMIT"]=nil ENV["MAGICK_DISK_LIMIT"]=nil end end # returns the default limits that imagemagick is using, when run with no "-limit" parameters # options: # :show_actual_values => true (default false) - will return integers instead of readable values def get_default_limits(options = {}) mem_fix = 1 parse_limits(options.merge(:get_current_limits => false)) end # returns the limits that imagemagick is running based on any "set_limits" calls def get_current_limits(options = {}) mem_fix = 1 parse_limits(options.merge(:get_current_limits => true)) end alias :get_limits :get_current_limits def parse_limits(options) show_actual_values = options[:show_actual_values] if options[:get_current_limits] status = self.execute('identify', '-list resource') raw_limits = status.return_value else # we run a raw shell command here to obtain # limits without applying command line limit params raw_limits = `identify -list resource` end actual_values, readable_values = parser.parse_limits(raw_limits) show_actual_values ? actual_values : readable_values end # parse_limits # returns a string suitable for passing as a set of imagemagick params # that contains all the limit constraints def get_limits_as_params retval = '' # we upcase the value here for newer versions of ImageMagick (>=6.8.x) @@resource_limits.each do |type, value| retval += " -limit #{type.to_s} #{value.upcase} " end retval end def parser @parser ||= MojoMagick::Util::Parser.new end end end mojo-magick-0.5.6/lib/image_magick/fonts.rb0000644000175000017500000000073212542772650020114 0ustar sophiesophiemodule ImageMagick module Fonts def get_fonts @parser ||= MojoMagick::Util::Parser.new raw_fonts = begin self.raw_command('identify', '-list font') rescue Exception => ex puts ex puts "Failed to execute font list with raw_command - trying straight up execute" `convert -list font` end @parser.parse_fonts(raw_fonts) end end end mojo-magick-0.5.6/lib/mojo_magick.rb0000644000175000017500000001516512542772650016653 0ustar sophiesophiecwd = File::dirname(__FILE__) require 'open3' initializers_dir = File::expand_path(File::join(cwd, 'initializers')) Dir.glob(File::join(initializers_dir, '*.rb')).each { |f| require f } require File::join(cwd, 'mojo_magick/util/parser') require File::join(cwd, 'mojo_magick/errors') require File::join(cwd, 'mojo_magick/command_status') require File::join(cwd, 'image_magick/resource_limits') require File::join(cwd, 'image_magick/fonts') require File::join(cwd, 'mojo_magick/opt_builder') require File::join(cwd, 'mojo_magick/font') require 'tempfile' # MojoMagick is a stateless set of module methods which present a convient interface # for accessing common tasks for ImageMagick command line library. # # MojoMagick is specifically designed to be efficient and simple and most importantly # to not leak any memory. For complex image operations, you will find MojoMagick limited. # You might consider the venerable MiniMagick or RMagick for your purposes if you care more # about ease of use rather than speed and memory management. # all commands raise "MojoMagick::MojoFailed" if command fails (ImageMagick determines command success status) # Two command-line builders, #convert and #mogrify, have been added to simplify # complex commands. Examples included below. # # Example #convert usage: # # MojoMagick::convert('source.jpg', 'dest.jpg') do |c| # c.crop '250x250+0+0' # c.repage! # c.strip # c.set 'comment', 'my favorite file' # end # # Equivalent to: # # MojoMagick::raw_command('convert', 'source.jpg -crop 250x250+0+0 +repage -strip -set comment "my favorite file" dest.jpg') # # Example #mogrify usage: # # MojoMagick::mogrify('image.jpg') {|i| i.shave '10x10'} # # Equivalent to: # # MojoMagick::raw_command('mogrify', '-shave 10x10 image.jpg') # # Example showing some additional options: # # MojoMagick::convert do |c| # c.file 'source.jpg' # c.blob my_binary_data # c.append # c.crop '256x256+0+0' # c.repage! # c.file 'output.jpg' # end # # Use .file to specify file names, .blob to create and include a tempfile. The # bang (!) can be appended to command names to use the '+' versions # instead of '-' versions. # module MojoMagick # enable resource limiting functionality extend ImageMagick::ResourceLimits extend ImageMagick::Fonts def MojoMagick::windows? mem_fix = 1 !(RUBY_PLATFORM =~ /win32/).nil? end def MojoMagick::execute(command, args, options = {}) # this suppress error messages to the console # err_pipe = windows? ? "2>nul" : "2>/dev/null" begin execute = "#{command} #{get_limits_as_params} #{args}" out, outerr, status = Open3.capture3(execute) CommandStatus.new execute, out, outerr, status rescue Exception => e raise MojoError, "#{e.class}: #{e.message}" end end def MojoMagick::execute!(command, args, options = {}) # this suppress error messages to the console # err_pipe = windows? ? "2>nul" : "2>/dev/null" status = execute(command, args, options) if !status.success? err_msg = options[:err_msg] || "MojoMagick command failed: #{command}." raise(MojoFailed, "#{err_msg} (Exit status: #{status.exit_code})\n Command: #{status.command}\n Error: #{status.error}") end status.return_value end def MojoMagick::raw_command(*args) self.execute! *args end def MojoMagick::shrink(source_file, dest_file, options) opts = options.dup opts.delete(:expand_only) MojoMagick::resize(source_file, dest_file, opts.merge(:shrink_only => true)) end def MojoMagick::expand(source_file, dest_file, options) opts = options.dup opts.delete(:shrink_only) MojoMagick::resize(source_file, dest_file, opts.merge(:expand_only => true)) end # resizes an image and returns the filename written to # options: # :width / :height => scale to these dimensions # :scale => pass scale options such as ">" to force shrink scaling only or "!" to force absolute width/height scaling (do not preserve aspect ratio) # :percent => scale image to this percentage (do not specify :width/:height in this case) def MojoMagick::resize(source_file, dest_file, options) retval = nil scale_options = [] scale_options << ">" unless options[:shrink_only].nil? scale_options << "<" unless options[:expand_only].nil? scale_options << "!" unless options[:absolute_aspect].nil? scale_options << "^" unless options[:fill].nil? scale_options = scale_options.join extras = [] if !options[:width].nil? && !options[:height].nil? geometry = "#{options[:width]}X#{options[:height]}" elsif !options[:percent].nil? geometry = "#{options[:percent]}%" else raise MojoMagickError, "Unknown options for method resize: #{options.inspect}" end if !options[:fill].nil? && !options[:crop].nil? extras << "-gravity Center" extras << "-extent #{geometry}" end retval = raw_command("convert", "\"#{source_file}\" -resize \"#{geometry}#{scale_options}\" #{extras.join(' ')} \"#{dest_file}\"") dest_file end def MojoMagick::available_fonts # returns width, height of image if available, nil if not Font.all end def MojoMagick::get_format(source_file, format_string) retval = raw_command("identify", "-format \"#{format_string}\" \"#{source_file}\"") end # returns an empty hash or a hash with :width and :height set (e.g. {:width => INT, :height => INT}) # raises MojoFailed when results are indeterminate (width and height could not be determined) def MojoMagick::get_image_size(source_file) # returns width, height of image if available, nil if not retval = self.get_format(source_file, %q|w:%w h:%h|) return {} if !retval width = retval.match(%r{w:([0-9]+) }) width = width ? width[1].to_i : nil height = retval.match(%r{h:([0-9]+)}) height = height ? height[1].to_i : nil raise(MojoFailed, "Indeterminate results in get_image_size: #{source_file}") if !height || !width {:width=>width, :height=>height} end def MojoMagick::convert(source = nil, dest = nil) opts = OptBuilder.new opts.file source if source yield opts opts.file dest if dest raw_command('convert', opts.to_s) end def MojoMagick::mogrify(dest = nil) opts = OptBuilder.new yield opts opts.file dest if dest raw_command('mogrify', opts.to_s) end def MojoMagick::tempfile(*opts) begin data = opts[0] rest = opts[1] ext = rest && rest[:format] file = Tempfile.new(["mojo", ext ? '.' + ext.to_s : '']) file.binmode file.write(data) file.path rescue Exception => ex raise ensure file.close end end end # MojoMagick mojo-magick-0.5.6/README.md0000644000175000017500000002065612542772650014561 0ustar sophiesophieMojoMagick ========== MojoMagick is a "dog simple, do very little" image library. It is basically a couple of stateless module methods that make it somewhat more convenient than calling ImageMagick by hand. The main reason to use MojoMagick is that you should consolidate your ImageMagick calls into one place, so why not do it here? If you improve on this tool, send me the patch. This tool came about because I wanted a fast, simple, lightweight, nothing-goes-wrong-with-it- because-it's-too-simple-to-break image tool. [![Gem Version](https://badge.fury.io/rb/mojo_magick.png)](http://badge.fury.io/rb/mojo_magick) Using it ======== Add to your Gemfile gem 'mojo_magick' Require it in your ruby code require 'mojo_magick' Go to town! Check out a couple of simple [examples, here](examples/) Examples ======== ## Image Resizing ### Obtain the size of an image (assuming image is "120wx222h") dimensions = MojoMagick::get_image_size(test_image) # ==> dimensions now holds a hash: {:height => 120, :width => 222} ### Resize an image so that it fits within a 100w x 200h bounding box (Note: this will scale an image either up or down to fit these dimensions which may not be what you want.) In this example, we overwrite our image, but if you pass in a different file for the second file name, a new file will be created with the resized dimensions MojoMagick::resize('/img/test.jpg', '/img/test.jpg', {:width=>100, :height=>200}) ### Resize an image so that it fills a 100 x 100 bounding box After this transformation, your image's short side will be 100px. This will preserve the aspect ratio. MojoMagick::resize('/img/infile.jpg', '/img/outfile.jpg', {:width=>100, :height=>100, :fill => true}) ### Resize an image so that it fills and is cropped to a 100 x 100 bounding box After this transformation, your image will be 100x100. But it does not distort the images. It crops out of the Center. MojoMagick::resize('/img/infile.jpg', '/img/outfile.jpg', {:width=>100, :height=>100, :fill => true, :crop => true}) ### Code sample of how to shrink all jpg's in a folder require 'mojo_magick' image_folder = '/tmp/img' Dir::glob(File::join(image_folder, '*.jpg')).each do |image| begin # shrink all the images *in place* to no bigger than 60pix x 60pix MojoMagick::shrink(image, image, {:width => 60, :height => 60}) puts "Shrunk: #{image}" rescue MojoMagick::MojoFailed => e STDERR.puts "Unable to shrink image '#{image}' - probably an invalid image\n#{e.message}" rescue MojoMagick::MojoMagickException => e STDERR.puts "Unknown exception on image '#{image}'\n#{e.message}" end end ## Setting Memory/Resource limits for ImageMagick Be sure you're upgraded to the current release of ImageMagick. set limits on disk, area, map and ram usage obtain/print a hash of default limits: puts MojoMagick::get_default_limits.inspect current\_limits shows same values: puts MojoMagick::get_current_limits.inspect MojoMagick::set_limits(:area => '32mb', :disk => '0', :memory => '64mb', :map => '32mb') puts MojoMagick::get_current_limits.inspect As of ImageMagick 6.6, you also have the ability to set `:threads` and `:time`. Read [ImageMagick docs on limits](http://www.imagemagick.org/script/command-line-options.php#limit) for more info. ## For more complex operations (thanks to Elliot Nelson for adding this code to the system) Two command-line builders, #convert and #mogrify, have been added to simplify complex commands. ### using #convert MojoMagick::convert('source.jpg', 'dest.jpg') do |c| c.crop '250x250+0+0' c.repage! c.strip c.set 'comment', 'my favorite file' end # Equivalent to: MojoMagick::raw_command('convert', 'source.jpg -crop 250x250+0+0 +repage -strip -set comment "my favorite file" dest.jpg') ### using #mogrify MojoMagick::mogrify('image.jpg') {|i| i.shave '10x10'} # Equivalent to: MojoMagick::raw_command('mogrify', '-shave 10x10 image.jpg') # Example showing some additional options: # assuming binary data that is rgb, 8bit depth and 10x20 pixels, :format => :rgb, :depth => 8, :size => '10x20'OAu MojoMagick::convert do |c| c.file 'source.jpg' c.blob my_binary_data, :format => :rgb, :depth => 8, :size => '10x20' c.append c.crop '256x256+0+0' c.repage! c.file 'output.jpg' end # Use .file to specify file names, .blob to create and include a tempfile. The # bang (!) can be appended to command names to use the '+' versions # instead of '-' versions. ### Create a brand new image from data binary_data = '1111222233334444' MojoMagick::convert do |c| c.rgba8 binary_data, :format => :rgba, :depth => 8, :size => '2x2' c.file 'output.jpg' end ### Get a list of available fonts fonts = MojoMagick::get_fonts fonts.first => # ### Create a new image with text Note: Use with care. If you don't have fonts installed ImageMagick can spin off wildly leaving MojoMagick not knowing what to do. For Unix/MacOSX, you should install `freetype` and `ghostscript`. MojoMagick::convert(nil, fname) do |c| c.background 'black' c.fill 'white' c.gravity 'center' c.pointsize 80 c.size '200x200' c.label 'the bird is the word' end ### Generate a composite MojoMagick::convert(nil, 'composite_out.png') do |c| c.size '200x200' c.image_block do # first layer c.background 'blue' c.fill 'white' c.gravity 'northwest' c.label 'NW' end c.image_block do # second layer c.background 'transparent' c.fill 'red' c.gravity 'southeast' c.label 'SE' end c.composite end Dependencies ============ This library has (in the past) been good for ruby 1.8.7 and beyond. Recent mods (as of 0.5.x) will require a more recent ruby (>1.9.3). If you're running on 1.8.7, you should be able to safely use 0.4.3 Do this by pinning it in your Gemfile gem 'mojo_magick', '0.4.3' Availablility ============= * [Github Repo](http://github.com/rcode5/mojo_magick) This is the current canonical branch. * Issues/Pull Requests can be submitted through the above repository. Contributions ============= Got a fix? Got a feature? * fork it * make a branch (named appropriately) * write your code * write your tests * test it (`rake` will run the tests) * submit a pull request Note: please don't change the version. We'll do that when we merge in the new code Recent Changes ============== #### Version 0.5.4 * Include image magick commandline failure from raw_command (on failure) * moved to Popen3 * added checks for Popen3 on windows * updated README to include info about submissions * probably no good for ruby 1.8.7 anymore #### Version 0.5.1 * add `LICENSE.txt` and update README * add `examples/` directory * add support for fonts * add support for building multi-layer images with image blocks (no explicit temp file creation) * [Moved repo to rcode5](http://github.com/rcode5/mojo_magick) Current support and maintenance is happening here. * added `simplecov` for test coverage reports #### Versions 0.4.x * Add rake tasks for gem building and tests * code cleanup * better handling of `gravity` parameter #### Version 0.3.0 * Add new github repo * added gemspec for building gem with bundler * updated tests for ImageMagick 6.6 * added ability to do fill + crop resizing * bumped version to 0.3.0 * [new github repo](https://github.com/bunnymatic/mojo_magick) References ========== * [Original SVN MojoMagick repository](http://www.misuse.org/science/2008/01/30/mojomagick-ruby-image-library-for-imagemagick/) - Initiated and developed by Steve Midgley * [ImageMagick](http://www.imagemagick.org/) * [FreeType](http://www.freetype.org) * [Ghostscript](http://www.ghostscript.com/) Copyright (c) 2013 Jon Rogers Copyright (c) 2008 Steve Midgley, released under the [MIT license](LICENSE.txt) Credit to Elliot Nelson for significant code contributions. Thanks Elliot!