
æè¿ãDã©ã€ãã©ãªã®
ã°ã©ãã£ãã¯ããã±ãŒãžã®ãªã¯ãŒã¯ãå®äºããŸããã
std.algorithmããã³
std.rangeã¢ãžã¥ãŒã«ã«è§ŠçºãããŠã次ã®ç®æšãéæããããšããŸããã
- ãã¹ãŠãå°ããªçµã¿åããå¯èœãªã³ã³ããŒãã³ããšããŠæç€ºãã
- æé»ã®ã³ããŒãé¿ããã§ããã°é
å»¶èšç®ã䜿çšãã
- ãã³ãã¬ãŒãã䜿çšããŠãã³ãŒãèšè¿°ã®ããã©ãŒãã³ã¹ãšå¹çãæ¹åããŸã
æåã®ããŒãžã§ã³ãããç»ååŠçããã±ãŒãžã®ãã¹ãŠã®ã³ã³ããŒãã³ãã¯ãè²ã®çš®é¡ã«ãã£ãŠãã©ã¡ãŒã¿ãŒåãããŸããã ããã¯ãã°ã©ãã£ãã¯ã©ã€ãã©ãªãå®è£
ããæšæºçãªæ¹æ³ã§ã¯ãããŸãããã»ãšãã©ã®å ŽåãOOPã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠç¹å®ã®çš®é¡ã®ç»åè²ãæœè±¡åãããããã¹ãŠã®ç»åãåäžãã¯ã»ã«åœ¢åŒã«å€æããŸãã ãã ããã»ãšãã©ã®å Žåãããã¯ã¡ã¢ãªãšæéã®ç¡é§ã§ããéåžžãéçºè
ã¯ãç»åããŒã¿ããŠãŒã¶ãŒã«ãã£ãŠå
¥åãããã¢ããªã±ãŒã·ã§ã³ïŒã°ã©ããšãã£ã¿ãŒãªã©ïŒãé€ããç»åãã©ã®ç¹å®ã®åœ¢åŒã§è¡šç€ºãããããäºåã«ç¥ã£ãŠããŸãã 代ããã«ãç§ã®ã©ã€ãã©ãªã¯ããã¹ãŠã®ç»åã¿ã€ããè²ã®ãã©ã¡ãŒã¿ãŒã¿ã€ããæã€ãã³ãã¬ãŒããšããŠå®£èšããŠããŸãã
ã©ã€ãã©ãªã§ã®äœæ¥ã®çµæã«éåžžã«æºè¶³ããŠããã®ã§ããã®æçš¿ã§è峿·±ãç¹ãå
±æããããšæããŸãã
ã©ã€ãã©ãªã¯
viewã®å®çŸ©ã§å§ãŸã
ãŸã ïŒ
éçã€ã³ã¿ãŒãã§ã€ã¹ã宣èšãããã®ã¡ãœããã¯ãstd.rangeãããšãã°isInputRangeã§äœ¿çšãããã¡ãœãããšåã
ã§ã ã OOPã«æå³ã䌌ãŠããã€ã³ã¿ãŒãã§ã€ã¹ã宣èšãã代ããã«ãDã®éçã€ã³ã¿ãŒãã§ã€ã¹ã¯ãç¹å®ã®æ©èœã®å®è£
ãã¹ãïŒ
ããã¯ã¿ã€ãã³ã° ïŒã䜿çšããŠæ¡ä»¶ä»ãã§æ±ºå®ãã
ãŸã ã åãå®è£
ããæäœããšã©ãŒãªãã§ã³ã³ãã€ã«ãããããç¹å®ã®åãæã€å Žåãæ€èšŒã¯æåããŸãã éåžžãããã«ã¯
IsExpressionãŸãã¯
trait ã³ã³ãã€ã«ã䜿çšãããŸãã
std.range.ElementTypeãšåæ§ã«ããã¯ã»ã«ã®è²ã®ãã¥ãŒã§äœ¿çšãããã¿ã€ããååŸãããã³ãã¬ãŒã
ãå®çŸ©ããŸãã
次ã«ããã¥ãŒã®ããã€ãã®å°éåéãå®çŸ©ããŸãã
ç¹°ãè¿ããŸãããããã¯
isForwardRangeã®å®çŸ©ã«äŒŒãŠããŸãããã®ç¹æ®åã«åºæã®ããã€ãã®è¿œå æ©èœãšåæ§ã«ãåããã¹ãŠã®åºæ¬æ©èœãå®è£
ããŠããããšã確èªããŸãã
ãã¯ã»ã«ãžã®çŽæ¥ã¢ã¯ã»ã¹ã®å®è£
ã¯ã
ã¹ãã£ã³ã©ã€ã³ã®çŽæ¥ãã¥ãŒãä»ããŠæ±ºå®ã§ããããããããå®è£
ãã
ãã³ãã¬ãŒãããã¯ã¹ã€ã³ã宣èšããŸãã
ããšãã°ãã¡ã¢ãªå
ã®ç»åãèšè¿°ãã
ç»åãã³ãã¬ãŒããå®çŸ©ããŸãã
Dã®é
å㯠ããã€ã³ã¿ãŒãšé·ããä»ã
ãŠå®è£
ãããŸãïŒãŸããæ¡åŒµãŸãã¯æ¥çãããå Žåã«ã®ã¿ã¡ã¢ãªãèŠæ±ããŸãïŒããããã£ãŠãåŒ
ãã¯ã»ã«[w * y ... w *ïŒy + 1ïŒ]ã¯é
åã®ã³ããŒãäœæããŸããã
åäœãã¹ãã¯ãã³ã³ãã€ã«æã«ã
Imageã
isDirectViewã€ã³ã¿ãŒãã§ã€ã¹ã®æ¡ä»¶ãå®éã«æºãããŠããããšã確èªããŸãã
unittest { static assert(isDirectView!(Image!ubyte)); }
ããã§ã¯ããã®ã¢ãã«ã§äœãã§ããã§ããããïŒ
ãŸããå®éã«ãã¯ã»ã«ã®é
åãåç
§ããã«ãå¿
èŠã«å¿ããŠèšç®ããç»åãå®çŸ©ã§ããŸãã
ãã®åãååã®ãã³ãã¬ãŒãã¯ã
std.functional.binaryFunã䜿çšããŠãæååïŒ
æ··åãããŸãïŒãè¿°èªãŸãã¯ããªã²ãŒãïŒã©ã ãïŒã«å€æããŸãã ãã®é¢æ°ã¯æ»ãå
autoãæã¡ããã®é¢æ°å
ã§å®£èšããã
æ§é äœãè¿ãããã
æç¶ã åã¯
Voldemortåã®äŸã§ãã
1ã€ã®è²ã§å¡ãã€ã¶ãããæç¶ãåç»åã®æãåçŽãªäŸïŒ
è¿ããããã¥ãŒã®ã«ã©ãŒã¿ã€ãããã©ã¡ãŒã¿ãŒã¿ã€ãcããã©ã®ããã«æšæž¬ããããã«æ³šæããŠãã ããããã®ãããå®å
šä¿®é£Ÿåããªãå Žåã§ãã
solidïŒRGBïŒ1ã2ã3ïŒã10ã10ïŒã¯RGBãã¯ã»ã«ãããã¥ãŒãè¿ããŸãã
ãã®ã¢ãã«ã§è¡šçŸã§ãããã1ã€ã®ããšã¯ãããŸããŸãªæ¹æ³ã§ä»ã®ãã¥ãŒã倿ãããã¥ãŒãäœæããããšã§ãã äžè¬çã«äœ¿çšãããã³ãŒãã®å¥ã®ãã³ãã¬ãŒãããã¯ã¹ã€ã³ãå®çŸ©ããŸãã
éçãªifïŒisWritableViewïŒVïŒè¡ãèŠãŠã¿ãŸããã
ãããã¯ã
ãã¥ãŒ[xãy] = cã¹ããŒãã¡ã³ãããåºç€ãšãªããã¥ãŒã§ãµããŒããããŠããå Žåã«ã®ã¿å®çŸ©ããå¿
èŠãããããšã瀺ããŠããŸãã åºã«ãªããã¥ãŒã倿Žã§ããå Žåã«ã®ã¿ãã©ãããããåèšãã¥ãŒã倿Žå¯èœã«ãªããŸãã
ãã®é¢æ°ã䜿çšããŠãå¥ã®ãã¥ãŒã®é·æ¹åœ¢éšåã衚ã
ããªãã³ã°ãã¥ãŒãå®çŸ©ã§ããŸãã
ifïŒisViewïŒVïŒ ãã³ãã¬ãŒãå¶çŽã¯ãæåã®åŒæ°ã
isViewã€ã³ã¿ãŒãã§ã€ã¹ã®æ¡ä»¶ã«äžèŽããããšã
確èªããŸãã
åãšåãããã«ã
ããªãã³ã°ã¯
isDirectViewã䜿çšããŠãåºã«ãªãç»åããã¯ã»ã«ããµããŒãããŠããå Žåããã¯ã»ã«ã«çŽæ¥ã¢ã¯ã»ã¹ããŸãã çŽæ¥ãã¯ã»ã«ã¢ã¯ã»ã¹ã¯ãäžåºŠã«å€æ°ã®ãã¯ã»ã«ãæäœããå Žåã«åœ¹ç«ã¡ãŸããããã«ãããã·ãŒã±ã³ã·ã£ã«ã¢ã¯ã»ã¹ãšæ¯èŒããŠããã©ãŒãã³ã¹ãåäžããŸãã ããšãã°ãããã€ã¡ãŒãžãå¥ã®ã€ã¡ãŒãžã«ã³ããŒããå Žåãåãã¯ã»ã«ã®å€ãåå¥ã«å²ãåœãŠãããããã¹ã©ã€ã¹ã³ããŒïŒDã®ã¿ã€ãã»ãŒããª
memcpy眮æïŒã䜿çšããæ¹ãã¯ããã«é«éã§ãã
cropãšåãèãæ¹ã䜿çšããŠãæè¿åã¢ã«ãŽãªãºã ã«åŸã£ãŠå¥ã®ãã¥ãŒãã¿ã€ã«è¡šç€ºãŸãã¯ã¹ã±ãŒãªã³ã°ãããã¥ãŒãå®è£
ã§ããŸãïŒããè€éãªã¹ã±ãŒãªã³ã°ã¢ã«ãŽãªãºã ã¯ãåœä»€åã¹ã¿ã€ã«ã§ããé©åã«å®è£
ãããŸãïŒã ã³ãŒãã¯
cropã«éåžžã«äŒŒãŠãããããããã«ã¯å«ããŸããã
cropããœãŒã¹ãéåžžã®åŒæ°ãšããŠäœ¿çšããå Žåã§ãããã®é¢æ°ãªã©ã®äœ¿çšç®çã¯ãå
ã®ãã¥ãŒã®ã¡ãœããã§ãããã®ããã«ãªããŸãïŒ
someView.nearestNeighborïŒ100ã100ïŒ.tileïŒ1000ã1000ïŒ.cropïŒ50ã50ã950ã 950ïŒ ã ãã®å¯èœæ§ã¯ã
ãUniform Function Call Syntaxã ïŒãŸãã¯åã«UFCSïŒãšåŒã°ããèšèªã®
æ©èœã«ãããŸããããã«ããã
funïŒaãb ...ïŒã®ä»£ããã«
a.funïŒb ...ïŒãèšè¿°ã§ããŸãã ãã®æ©èœã®äž»ãªå©ç¹ã¯ã
ãã§ãŒã³ãæŽçããæ©èœïŒ
a.fun1ïŒïŒãFun2ïŒïŒã Fun3ïŒfun2ïŒfun1ïŒaïŒïŒ ïŒã®ä»£ããã«
Fun3ïŒ ïŒã§ãããããã¯Phobosããã³ãã®ããã±ãŒãžã§æå€§éã«äœ¿çšãããŸãã
ãã¥ãŒã®ãµã€ãºãå€ãããªãåçŽãªå€æã®å Žåãåãã¯ã»ã«åº§æšãžã®ãŠãŒã¶ãŒæå®ã®åŒã®é©çšãç°¡çŽ åããè£å©é¢æ°ãå®çŸ©ã§ããŸãã
warpã¯æž¡ãããåŒãæ€èšŒããããã«ããªãããŒãªæ¹æ³ã䜿çšããŸãã ãã ãã
testWarpY颿°
ã¯ãã³ãã¬ãŒãåŒæ°ãšããŠãŒãã®ãã³ãã¬ãŒããšããŠå®£èšãããŸãã ããã«ãããã³ã³ãã€ã©ãŒã¯ã䜿çšããããŸã§ãã®é¢æ°ã®æ¬äœã®ã»ãã³ãã£ãã¯åæãè¡ããªããªããŸãã ãŸããã¹ã³ãŒãã«
xããªãããã
yExprã
xã䜿çšããªãå Žåã«ã®ã¿æ£åžžã«ã€ã³ã¹ããŒã«ã§ããŸãã åŒ
__traitsïŒã³ã³ãã€ã«ãtestWrapYïŒïŒïŒã¯ããããã§ãã¯ããã ãã§ãã ããã«ãããå®å
šã«å®è¡ã§ãããšç¢ºä¿¡ããŠããå Žåã«ã®ã¿ãçŽæ¥ãã¥ãŒ
ã¹ãã£ã³ã©ã€ã³ãå®çŸ©ã§ããŸãã äŸïŒ
q {...}æ§æã¯ãæåå宿°ãå®çŸ©ãã䟿å©ãªæ¹æ³ã§ãã ãã®ãšã³ããªã¯éåžžDã³ãŒãã«äœ¿çšããããã®åŸDã³ãŒããã©ããã§æ··åãããŸãã åŒã¯æ··åå Žæã®ãã¹ãŠã®æåã«ã¢ã¯ã»ã¹ã§ããŸãããã®å Žåãããã¯
Wrappedæ§é ã®
ã¯ãŒã颿°ãš
testWarpYã¡ãœããã§ãã
vflipã¯
ã¹ãã£ã³ã©ã€ã³ã¡ãœããã®å®£èšã«å¿
èŠãªæåã®2ã€ã®æ¡ä»¶ãæºãããŠããããã
someViewãoneã®å Žåã
someView.vflipïŒïŒã¯çŽæ¥ãã¥ãŒã«ãªããŸãã ãããŠãããã¯
vflipåºåã®æç€ºçãªæ€èšŒãªãã§éæãããŸããã
䜿çšãããæœè±¡åã¯åçãªå€æ
æ§ã«äŸåããªããããã³ã³ãã€ã©ã¯ãã¹ãŠã®å€æã¬ã€ã€ãŒã®åŒã³åºããèªç±ã«çµã¿èŸŒãããšãã§ããŸãã ç»åã2åå転ããŠãæäœã¯çæããããå®éã«ã¯
i [ 5ã5 ]ããã³
i.hflipïŒïŒãHflipïŒïŒ[5ã5]ã¯åããã·ã³ã³ãŒããçæããŸãã
ããåªããããã¯ãšã³ããåããDã³ã³ãã€ã©ãŒã¯ãããã«ç©æ¥µçãªæé©åãå®è¡ã§ããŸãïŒããšãã°ãX軞ãšY軞ãå転ãã
flipXY颿°ãããã³
src.flipXY ïŒïŒãšããŠ
rotateCWïŒç»åãåæèšåãã«90床å転ïŒãå®çŸ©ããå Žåããã®åŸãæé©åäžã«4ã€ã®æ£åžžãª
rotateCWåŒã³åºããã«ããã¢ãŠããããŸãã
ãã¯ã»ã«èªäœã®æäœã«ç§»ããŸãããã
std.algorithmã®äž»ãªé¢æ°ã¯
mapã§ ãå¥ã®ç¯å²ã«åŒãé
å»¶çã«é©çšãã
ç¯å²ãè¿ããŸãã ã«ã©ãŒ
ãããã§ã¯ããã®ã¢ã€ãã¢ãè²ã«äœ¿çšããŠããŸãã
colorMapã䜿çšããŠãç»åã®è²ãå転ãã颿°ãå®çŸ©ããã®ã¯ç°¡åã§ãïŒ
alias invert = colorMap!q{~c};
colorMapã§ã¯ããœãŒã¹ãšçµæã®è²ã¿ã€ããäžèŽãããå¿
èŠã¯ãããŸããã ããã«ãããè²å€æã«äœ¿çšã§ããŸãïŒ
readïŒ "image.bmp"ïŒãParseBMPïŒRGBïŒïŒãColorMapïŒïŒC => BGRXïŒcbãcgãcrïŒïŒã¯ãRGBãããããããBGRXãã¥ãŒãšããŠè¿ããŸãã
ç»ååŠçã¯ãå€ãã®å Žå
ã䞊ååã«é©ããŠããŸãã
std.parallelismã¯ã䞊åç»ååŠçã®ã¿ã¹ã¯ã
ç°¡åã«ããã®ã«åœ¹ç«ã¡ãŸãã
parallelã
std.parallelismã«ååšãã颿°ãšååãå
±æããŠããå Žåã§ããç°ãªãã·ã°ããã£ãæã¡ãç°ãªãã¿ã€ãã§æ©èœãããããç«¶åã¯ãããŸããã
åæã«ã
image.processïŒïŒã
image.parallelïŒïŒSegment => segment.processïŒïŒïŒãVjoinïŒïŒã«çœ®ãæããããšã§ãæäœãè€æ°ã®ã¹ã¬ããã«åå²ã§ããŸãã
å®éã®äŸïŒ
- çãã¢ãã¡ãŒã·ã§ã³ãäœæããŸãã
ã³ãŒã import std.algorithm; import std.parallelism; import std.range; import std.stdio; import std.string; import ae.utils.geometry; import ae.utils.graphics.color; import ae.utils.graphics.draw; import ae.utils.graphics.gamma; import ae.utils.graphics.image; void main() { enum W = 4096; const FG = L16(0); const BG = L16(ushort.max); auto image = Image!L16(W, W); image.fill(BG); enum OUTER = W/2 * 16/16; enum INNER = W/2 * 13/16; enum THICK = W/2 * 3/16; image.fillCircle(W/2, W/2, OUTER, FG); image.fillCircle(W/2, W/2, INNER, BG); image.fillRect(0, W/2-INNER, W/2, W/2+INNER, BG); image.fillRect(W/2-THICK/2, W/2-INNER, W/2+THICK/2, W/2+INNER, FG); enum frames = 32; foreach (n; frames.iota.parallel) image .rotate(TAU * n / frames, BG) .copy .downscale!(W/16) .lum2pix(gammaRamp!(ushort, ubyte, ColorSpace.sRGB)) .toPNG .toFile("loading-%02d.png".format(n++)); }
ãã®ããã°ã©ã ã¯ã16ãããã®æããã䜿çšããŠå
ã®ç»åãããé«ãè§£ååºŠã§æç»ããçž®å°åŸã«8ãããã®sRGBç»åã«å€æããŸãã ãºãŒã ã¢ãŠããããšãšã€ãªã¢ã·ã³ã°ãåé¿ããã æ£ç¢ºãªãµã€ãºå€æŽã«ã¯è²å€æãå¿
èŠã§ãã
PNGãã¬ãŒã ãGIFã«å€æããåŸã¯æ¬¡ã®ããã«ãªããŸãã

- ãã³ãã«ããéåã®ã°ã¬ãŒãã¯ã€ãç»åã®ã¬ã³ããªã³ã°ïŒ
ã³ãŒã auto mandelbrot(int w, int h) { import std.algorithm, std.range; import ae.utils.graphics.view; return procedural!((x, y) { auto c = (2.0*x/w - 1.5) + (2.0*y/h - 1.0)*1i; return cast(ubyte)(1+ recurrence!((a, n) => c + a[n-1]^^2)(0+0i) .take(ubyte.max) .countUntil!(z => z.re^^2 + z.im^^2 > 4)); })(w, h); } void main() { import std.stdio; import ae.utils.graphics.image; mandelbrot(500, 500).toPNG().toFile("mandel.png"); }
ãã®ããã°ã©ã ã¯ãDç¯å²ã§recurrence ã takeããã³countUntilããªããã£ãã䜿çšããè€éãªæ°å€ã®çµã¿èŸŒã¿ãµããŒãã䜿çšããŠãéåžžã¯å®è£
ããã®ã«å€ãã®è¡ãå¿
èŠãšããã¢ã«ãŽãªãºã ãç°¡æœã«å®è£
ã§ããŸãïŒãã ããçµã¿èŸŒã¿ã®è€éãªæ°å€ã¯ãçŸåšstd.complexã«åã£ãŠä»£ãã廿¢ããã€ã€ãããŸã ïŒã
ä»äºã®çµæïŒ
ãã³ãã¬ãŒãã¢ãããŒãã¯ãããã©ãŒãã³ã¹ã®å€§å¹
ãªåäžãçŽæããŸãã ç°¡åãªãã³ãããŒã¯ãšããŠããã®ããã°ã©ã ã¯ãã£ã¬ã¯ããªå
ã®ãã¹ãŠã®ç»åã®ã¹ã±ãŒã«ã25ïŒ
åæžããŸãã
ã³ãŒã import std.file; import std.path; import std.stdio; import ae.utils.graphics.color; import ae.utils.graphics.gamma; import ae.utils.graphics.image; void main() { alias BGR16 = Color!(ushort, "b", "g", "r"); auto gamma = GammaRamp!(ushort, ubyte)(2.2); foreach (de; dirEntries("input", "*.bmp", SpanMode.shallow)) { static Image!BGR scratch1; static Image!BGR16 scratch2, scratch3; de .read .parseBMP!BGR(scratch1) .parallel!(segment => segment .pix2lum(gamma) .copy(scratch2) .downscale!4(scratch3) .lum2pix(gamma) .copy )(4) .vjoin .toBMP .toFile(buildPath("output-d", de.baseName)); } }
åçã®
ImageMagickã³ãã³ãã䜿çšããçµæãæ¯èŒããŸããã
convert \ input/*.bmp \ -depth 16 \ -gamma 0.454545 \ -filter box \ -resize 25
ããŒãžã§ã³Dã¯4ã5åé«éã«å®è¡ãããŸãã ãã¡ãããããã¯äžå
¬å¹³ãªæ¯èŒã§ããäž¡æ¹ã16ãããè²æ·±åºŠãã¬ã³ãè£æ£ããã«ãã¹ã¬ããã䜿çšããåãã¢ãŒããã¯ãã£åãã«æé©åãããŠããå Žåã§ããDããã°ã©ã ã«ã¯ãã®ã¿ã¹ã¯çšã«ç¹å¥ã«æé©åãããã³ãŒããå«ãŸããŠããŸãã ããŸããŸãªJITãã¯ããã¯ãèæ
®ããªããšãããã±ãŒãžãæ±çšç»ååŠçã©ã€ãã©ãªãšæ¯èŒã§ããŸããã
ã°ã©ãã£ãã¯ããã±ãŒãž
ã¯GitHubã§å
¥æã§ããŸã ã ãã®èšäºã«è²¢ç®ããŠãããDavid Ellsworthã«æè¬ããŸãã