ASCII碼藝術是一種技術,它利用ASCII標 准中的可打印字符來產生視覺藝術效果。在歷史上它有其存在的目的,當時的打印機還無法打印圖片,並且當時在郵件中嵌入圖像還無法實現,所以它也用於郵件 中。本文中,我將為你呈現一個非常簡單的ASCII碼藝術產生器,它由Java語言編寫,並可以配置字體和對比度。因為該產生器是我在周末用幾個小時創建 的,所以它還不完美,但卻是一個有趣的實驗。在下面你可以看到實現代碼,並且我將解釋它的工作原理。
算法
這個算法很簡單。首先,我們將ASCII碼藝術品中要用到的每一個字符轉化成一張圖片,並緩存它。然後,我們遍歷原始圖像,對於每個字符大小的圖片塊,找出 能最佳匹配它的字符。為了實現這一步,我們首先對原始圖像做一些預處理:我們先將圖像轉換為灰度圖,然後讓其通過一個阈值濾波器,此時就得到了一個黑白對比圖,我們可以將其與每個字符對比並計算差值。接著,對每個圖片塊選取最相似的字符,一直進行下去,直到整個圖像都轉換完成。此外,我們還可以根據需要調 整阈值大小來影響對比度,並增強最終的結果。
為了實現這一點,一個非常簡單的方法是將紅、綠、藍的值都設置成三種顏色的平均值:
紅=綠=藍 =(紅+綠+藍)/ 3
如果這個值低於阈值,我們就將它設置成白色,否則我們將其設置成黑色。最後,我們將圖像與每個字符以像素為單位進行比較並計算出平均誤差。如下面的圖片和代碼片段所示:
int r1 = (charPixel >> 16) & 0xFF;
int g1 = (charPixel >> 8) & 0xFF;
int b1 = charPixel & 0xFF;
int r2 = (sourcePixel >> 16) & 0xFF;
int g2 = (sourcePixel >> 8) & 0xFF;
int b2 = sourcePixel & 0xFF;
int thresholded = (r2 + g2 + b2) / 3 < THRESHOLD ? 0 : 255;
error = Math.sqrt((r1 - thresholded) * (r1 - thresholded) +
(g1 - thresholded) * (g1 - thresholded) + (b1 - thresholded) * (b1 - thresholded));
因為顏色是存儲在單個整數中,所以我們首先提取單個顏色成分並執行上面我解釋的計算。另一個挑戰是准確地測量字符尺寸,並以它們為中心作圖。在試驗了多種方法之後,我最終發現這個方法已經足夠好:
Rectangle rect = new TextLayout(Character.toString((char) i), fm.getFont(),
fm.getFontRenderContext()).getOutline(null).getBounds();
g.drawString(character, 0, (int) (rect.getHeight() - rect.getMaxY()));
你可以從GitHub上下載完整的源代碼。
下面是一些使用不同字體尺寸和阈值的例子。
原文鏈接: korhner 翻譯: ImportNew.com - PyPer