<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          字符作畫,我用字符畫個冰墩墩

          共 1769字,需瀏覽 4分鐘

           ·

          2022-02-17 19:18

          哈嘍,大家好啊,我是阿朗。

          已經 2022 年了,最近北京冬奧會的吉祥物冰墩墩很火,據(jù)說一墩難求,各種視頻新聞應接不暇。程序員要有程序員的方式,今天我來用 Java 畫一個由字符組成的冰墩墩送給大家,這篇文章記錄字符圖案的生成思路以及過程。

          下面是一個由字符W@#&8*0. 等字符組成的冰墩墩圖案。

          字符冰墩墩

          1. 字符圖案思路

          我們都知道數(shù)字圖片是一個二維圖像,它使用一個有限的二維數(shù)組保存每個像素點顏色信息,這些像素點的顏色信息通常使用 RGB 模式進行記錄。所以從本質上看,我們常見的圖片就是一個保存了像素信息的二維數(shù)組。

          像素圖片 - 來自維基百科

          基于以上的圖片原理,我們可以發(fā)現(xiàn),如果想要把一個圖片轉換成字符圖案,只需要把每個像素點的顏色信息轉換成某個字符就可以了,所以可以理出把圖片轉換成字符圖案的步驟如下。

          1. 縮放圖片到指定大小,為了保證輸出的字符數(shù)量不會太多。
          2. 遍歷圖片的像素點,獲取每個像素點的顏色信息。
          3. 根據(jù)像素點的顏色信息,轉換成灰度(亮度)信息。
          4. 把亮度信息轉換成相應的字符。
          5. 輸出字符圖案,也就是打印二維字符數(shù)組。

          2. 圖片的縮放

          如上所述,我們既然想要把每個像素點的顏色信息轉換成某個字符,如果像素點過多的話,雖然會增加字符圖片的還原度,但是看起來會非常麻煩,因為那么多字符你的屏幕可能顯示不完。

          因此,我們要先對圖片進行縮放,縮放到一定大小后再進行字符化。這里為了方便,直接使用 Java 自帶的圖片處理方式進行圖片縮放,下面的代碼示例都是指定寬度進行縮放,高度等比例計算后進行縮放。

          Java 中調整圖片大小主要有兩種方式:

          1. 使用 java.awt.Graphics2D 調整圖片大小。
          2. 使用 Image.getScaledInstance 調整圖片大小。

          2.1. java.awt.Graphics2D

          Graphics2D 是 Java 平臺提供的可以渲染二維形狀、文本、圖像的基礎類,下面是使用 Graphics2D 進行圖片大小調整的簡單示例。

          /**
          ?*?圖片縮放
          ?*
          ?*?@param?srcImagePath??圖片路徑
          ?*?@param?targetWidth???目標寬度
          ?*?@return
          ?*?@throws?IOException
          ?*/

          public?static?BufferedImage?resizeImage(String?srcImagePath,?int?targetWidth)?throws?IOException?{
          ????Image?srcImage?=?ImageIO.read(new?File(srcImagePath));
          ????int?targetHeight?=?getTargetHeight(targetWidth,?srcImage);
          ????BufferedImage?resizedImage?=?new?BufferedImage(targetWidth,?targetHeight,?BufferedImage.TYPE_INT_RGB);
          ????Graphics2D?graphics2D?=?resizedImage.createGraphics();
          ????graphics2D.drawImage(srcImage,?0,?0,?targetWidth,?targetHeight,?null);
          ????graphics2D.dispose();
          ????return?resizedImage;
          }

          /**
          ?*?根據(jù)指定寬度,計算等比例高度
          ?*
          ?*?@param?targetWidth???目標寬度
          ?*?@param?srcImage??????圖片信息
          ?*?@return
          ?*/

          private?static?int?getTargetHeight(int?targetWidth,?Image?srcImage)?{
          ????int?targetHeight?=?srcImage.getHeight(null);
          ????if?(targetWidth?null))?{
          ????????targetHeight?=?Math.round((float)targetHeight?/?((float)srcImage.getWidth(null)?/?(float)targetWidth));
          ????}
          ????return?targetHeight;
          }

          代碼中的 BufferedImage.TYPE_INT_RGB 表示所使用的顏色模型,所有的顏色模型可以在 Java doc - Image 文檔中看到。

          調整大小后的圖片可以通過以下方式保存。

          BufferedImage?image?=?resizeImage("/Users/darcy/Downloads/bingdundun.jpeg",?200);
          File?file?=?new?File("/Users/darcy/Downloads/bingdundun_resize.jpg");
          ImageIO.write(image,?"jpg",?file);

          下面把原圖為 416 x 500 的冰墩墩圖片縮放到 200 x 240 的效果。

          Java 圖片縮放

          2.2. Image.getScaledInstance

          這是 Java 原生功能調整圖片大小的另一種方式,使用這種方式調整圖片大小簡單方便,生成的圖片質量也不錯,代碼比較簡潔,但是這種方式的效率并不高。

          /**
          ?*?圖片縮放
          ?*
          ?*?@param?srcImagePath??圖片路徑
          ?*?@param?targetWidth???目標寬度
          ?*?@return
          ?*?@throws?IOException
          ?*/

          public?static?BufferedImage?resizeImage2(String?srcImagePath,?int?targetWidth)?throws?IOException?{
          ????Image?srcImage?=?ImageIO.read(new?File(srcImagePath));
          ????int?targetHeight?=?getTargetHeight(targetWidth,?srcImage);
          ????Image?image?=?srcImage.getScaledInstance(targetWidth,?targetHeight,?Image.SCALE_DEFAULT);
          ????BufferedImage?bufferedImage?=?new?BufferedImage(targetWidth,?targetHeight,?BufferedImage.TYPE_INT_RGB);
          ????bufferedImage.getGraphics().drawImage(image,?0,?0,?null);
          ????return?bufferedImage;
          }
          //?getTargetHeight?同?java.awt.Graphics2D?中示例代碼

          代碼中的 Image.SCALE_DEFAULT 表示圖片縮放使用的算法,在Java doc - Image 文檔中可以查看所有可以使用的算法。

          3. RGB 灰度計算

          我們知道圖片是由像素點組成的,每個像素點存儲了顏色信息,通常是 RGB 信息,所以我們想要把每個像素點轉換成字符,也就是把像素點中的 RGB 信息的灰度表達出來,不同的灰度給出不同的字符進行表示。

          比如我們把灰度分為 10 個等級,每個等級從高到低選擇一個字符進行標識。

          'W',?'@',?'#',?'8',?'&',?'*',?'o',?':',?'.',?'?'

          那么如何進行灰度計算呢?目前常見的計算方法有平均值法、加權均值法、伽馬校正法等。這里直接使用與伽馬校正線性相似的數(shù)學公式進行計算,這也是 MATLAB、 Pillow和 OpenCV 使用的方法。

          4. 輸出字符圖片

          前期準備已經完成了,我們已經把圖片進行了縮放,同時也知道了如何把圖片中的每個像素點上的 RGB 信息轉換成灰度值,那么我們只需要遍歷縮放后的圖片的 RGB 信息,進行灰度轉換,然后選擇對應的字符進行打印即可。

          public?static?void?main(String[]?args)?throws?Exception?{
          ????BufferedImage?image?=?resizeImage("/Users/darcy/Downloads/bingdundun.jpeg",?150);
          ????printImage(image);
          }

          /**
          ?*?字符圖片打印
          ?*
          ?*?@param?image
          ?*?@throws?IOException
          ?*/

          public?static?void?printImage(BufferedImage?image)?throws?IOException?{
          ????final?char[]?PIXEL_CHAR_ARRAY?=?{'W',?'@',?'#',?'8',?'&',?'*',?'o',?':',?'.',?'?'};
          ????int?width?=?image.getWidth();
          ????int?height?=?image.getHeight();
          ????for?(int?i?=?0;?i?????????for?(int?j?=?0;?j?????????????int?rgb?=?image.getRGB(j,?i);
          ????????????Color?color?=?new?Color(rgb);
          ????????????int?red?=?color.getRed();
          ????????????int?green?=?color.getGreen();
          ????????????int?blue?=?color.getBlue();
          ????????????//?一個用于計算RGB像素點灰度的公式
          ????????????Double?grayscale?=?0.2126?*?red?+?0.7152?*?green?+?0.0722?*?blue;
          ????????????double?index?=?grayscale?/?(Math.ceil(255?/?PIXEL_CHAR_ARRAY.length)?+?0.5);
          ????????????System.out.print(PIXEL_CHAR_ARRAY[(int)(Math.floor(index))]);
          ????????}
          ????????System.out.println();
          ????}
          }

          //?resizeImage?同第二部分代碼

          這里我選擇一張冰墩墩的圖片,可以看到輸出后的效果。

          5. 其他字符圖片

          下面是一些其他圖片轉字符圖的效果展示。

          2022 年,虎虎生威字符畫。

          老虎字符畫

          進擊的巨人人物 - 三笠字符畫。

          三笠字符畫

          一如既往,文章中的代碼存放在:github.com/niumoo/lab-notes

          參考

          [1] https://www.kdnuggets.com/2019/12/convert-rgb-image-grayscale.html

          [2] https://en.wikipedia.org/wiki/Grayscale

          ---- END ----

          Hello world : )?這篇文章就到這里了,我是阿朗,點贊和在看,動力無限,求關注。

          點個在看,加油充電~??

          瀏覽 112
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人女人18女人毛片 | 亚洲AV永久无码精品久久麻豆 | 成人A一级毛片免费看视频 | 色噜噜人妻av中文字幕 | 国产久久久久 |