Java圖片轉(zhuǎn)字符圖片的生成方法
前面介紹了一篇java實(shí)現(xiàn)圖片灰度化處理的小demo,接下來(lái)再介紹一個(gè)有意思的東西,將一個(gè)圖片轉(zhuǎn)換成字符圖片
借助前面圖片灰度化處理的知識(shí)點(diǎn),若我們希望將一張圖片轉(zhuǎn)成字符圖片,同樣可以遍歷每個(gè)像素點(diǎn),然后將像素點(diǎn)由具體的字符來(lái)替換,從而實(shí)現(xiàn)字符化處理
基于上面這個(gè)思路,具體的實(shí)現(xiàn)就很清晰了
@Test public void testRender() throws IOException { String file = "http://i0.download.fd.52shubiao.com/t_960x600/g1/M00/10/17/oYYBAFWvR5-IeXHuAAd5kPb8eSgAACm0QF50xIAB3mo414.jpg"; // 從網(wǎng)絡(luò)上下載圖片 BufferedImage img = ImageIO.read(FileReadUtil.getStreamByFileName(file)); int w = img.getWidth(), h = img.getHeight(); // 創(chuàng)建新的字符圖片畫板 BufferedImage gray = new BufferedImage(w, h, img.getType()); Graphics2D g2d = gray.createGraphics(); g2d.setColor(null); g2d.fillRect(0, 0, w, h); Font font = new Font("宋體", Font.BOLD, 1); g2d.setFont(font); for (int x = 0; x < w; x ++) { for (int y = 0; y < h; y ++) { g2d.setColor(ColorUtil.int2color(img.getRGB(x, y))); g2d.drawString("灰", x, y); } } g2d.dispose(); System.out.printf("渲染完成"); }
注意上面的實(shí)現(xiàn),在會(huì)字符的時(shí)候,先取出源像素點(diǎn)的色彩,然后重新設(shè)置給g2d,這個(gè)int轉(zhuǎn)color也比較簡(jiǎn)單,實(shí)現(xiàn)如下
public static Color int2color(int color) { int a = (0xff000000 & color) >>> 24; int r = (0x00ff0000 & color) >> 16; int g = (0x0000ff00 & color) >> 8; int b = (0x000000ff & color); return new Color(r, g, b, a); }
這樣就實(shí)現(xiàn)了一個(gè)基礎(chǔ)版的轉(zhuǎn)字符圖了,實(shí)際跑一下看看效果
這下尷尬了,輸出的并不是我們預(yù)期的字符圖,那么問(wèn)題出在哪呢?
仔細(xì)看上面的文字大小為1,文字太小,導(dǎo)致即使是有字符組件的圖,最終肉眼看起來(lái)和原圖也沒啥區(qū)別
那么我們就試一下將這個(gè)文字搞大點(diǎn),將n*n個(gè)像素點(diǎn)作為一個(gè)文字渲染區(qū)域,這樣我們需要調(diào)整一下遍歷的步長(zhǎng);其次就是這個(gè)區(qū)域的顏色怎么定
直接取均值
/** * 求取多個(gè)顏色的平均值 * * @return */ Color getAverage(BufferedImage image, int x, int y, int w, int h) { int red = 0; int green = 0; int blue = 0; int size = 0; for (int i = y; (i < h + y) && (i < image.getHeight()); i++) { for (int j = x; (j < w + x) && (j < image.getWidth()); j++) { int color = image.getRGB(j, i); red += ((color & 0xff0000) >> 16); green += ((color & 0xff00) >> 8); blue += (color & 0x0000ff); ++size; } } red = Math.round(red / (float) size); green = Math.round(green / (float) size); blue = Math.round(blue / (float) size); return new Color(red, green, blue); }
另外的就是改一下遍歷的步長(zhǎng)
@Test public void testRender() throws IOException { String file = "http://i0.download.fd.52shubiao.com/t_960x600/g1/M00/10/17/oYYBAFWvR5-IeXHuAAd5kPb8eSgAACm0QF50xIAB3mo414.jpg"; // 從網(wǎng)絡(luò)上下載圖片 BufferedImage img = ImageIO.read(FileReadUtil.getStreamByFileName(file)); int w = img.getWidth(), h = img.getHeight(); // 創(chuàng)建新的灰度圖片畫板 BufferedImage gray = new BufferedImage(w, h, img.getType()); Graphics2D g2d = gray.createGraphics(); g2d.setColor(null); g2d.fillRect(0, 0, w, h); int size = 12; Font font = new Font("宋體", Font.BOLD, size); g2d.setFont(font); for (int x = 0; x < w; x += size) { for (int y = 0; y < h; y += size) { Color avgColor = getAverage(img, x, y, size, size); g2d.setColor(avgColor); g2d.drawString("灰", x, y); } } g2d.dispose(); System.out.printf("渲染完成"); }
再次執(zhí)行之后結(jié)果如下,實(shí)現(xiàn)了我們的預(yù)期效果
最后再介紹一個(gè)更好用的姿勢(shì),直接使用開源項(xiàng)目https://github.com/liuyueyi/quick-media 來(lái)實(shí)現(xiàn)圖片字符畫
使用這個(gè)項(xiàng)目的 image-plugins 之后,生成一個(gè)灰度圖就很簡(jiǎn)單了
public void testCharImg() throws IOException { String img = "http://hbimg.b0.upaiyun.com/2b79e7e15883d8f8bbae0b1d1efd6cf2c0c1ed1b10753-cusHEA_fw236"; BufferedImage out = ImgPixelWrapper.build().setSourceImg(img).setBlockSize(2) .setPixelType(PixelStyleEnum.CHAR_COLOR) .setChars("小灰灰blog") .build() .asBufferedImg(); System.out.println(out); }
注意這個(gè)ImgPixelWrapper封裝類,處理基礎(chǔ)的字符處理之外,還支持生成灰度圖,gif圖轉(zhuǎn)字符動(dòng)畫,圖片像素化(如馬賽克...)
至于quick-media這個(gè)項(xiàng)目就更有意思了,java側(cè)若想生成酷炫的二維碼,選擇它絕對(duì)不會(huì)讓你失望;有興趣的小伙伴可以瞅一瞅
到此這篇關(guān)于Java圖片轉(zhuǎn)字符圖片的生成方法的文章就介紹到這了,更多相關(guān)Java圖片轉(zhuǎn)字符圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用FeignClient進(jìn)行微服務(wù)交互方式(微服務(wù)接口互相調(diào)用)
這篇文章主要介紹了使用FeignClient進(jìn)行微服務(wù)交互方式(微服務(wù)接口互相調(diào)用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03用Java實(shí)現(xiàn)小球碰壁反彈的簡(jiǎn)單實(shí)例(算法十分簡(jiǎn)單)
下面小編就為大家?guī)?lái)一篇用Java實(shí)現(xiàn)小球碰壁反彈的簡(jiǎn)單實(shí)例(算法十分簡(jiǎn)單)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08cookie、session和java過(guò)濾器結(jié)合實(shí)現(xiàn)登陸程序
這篇文章主要為大家詳細(xì)介紹了cookie、session和java過(guò)濾器結(jié)合實(shí)現(xiàn)登陸程序的具體代碼,感興趣的朋友可以參考一下2016-05-05Springboot自動(dòng)配置與@Configuration配置類詳解
這篇文章主要介紹了SpringBoot中的@Configuration與自動(dòng)配置,在進(jìn)行項(xiàng)目編寫前,我們還需要知道一個(gè)東西,就是SpringBoot對(duì)我們的SpringMVC還做了哪些配置,包括如何擴(kuò)展,如何定制,只有把這些都搞清楚了,我們?cè)谥笫褂貌艜?huì)更加得心應(yīng)手2022-07-07