1. 程式人生 > >抖音神器---Java實現圖片(Image)轉字元(ASCII)圖片

抖音神器---Java實現圖片(Image)轉字元(ASCII)圖片

最近抖音上挺火的一個小把戲,在記事本開啟,一整篇的亂碼字元,然後進過調整之後,出現一張由各種字元組成的黑白照片。先看一個效果圖

微信小程式體驗

直接體驗請微信掃碼

選擇字元圖片

 接下來我們就用Java來實現吧。

需要用到的工具類程式碼

非閃圖圖片轉字元畫到記事本

package com.xs.util.image;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import javax.imageio.ImageIO;

import com.xs.util.image.other.ImageHelper;
/**
 * Image2ASCII
 * @author 小帥丶
 * 2018年8月14日
 */
public class Image2ASCII{
	static String ascii = "
[email protected]
%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'."; static String base = "@#&$%*o!;.";//小帥丶使用這個字元 //main方法呼叫 public static void main(String[] args) throws Exception { load("G:/phone.jpg", "F:/gif/woman.txt");//靜態圖片轉字元儲存為txt檔案 } /** * 圖片轉字元 * @param imagePath 圖片路徑 * @param txtPath 文字存放路徑 * @throws IOException */ public static void load(String imagePath, String txtPath) throws IOException { BufferedImage image = ImageHelper.resize(ImageIO.read(new File(imagePath)),150,150); load(image, txtPath); } /** * 圖片轉字元 * @param bi BufferedImage圖片 * @param txtPath 文字存放路徑 * @throws IOException */ public static void load(BufferedImage bi, String txtPath) throws IOException { try { int width = bi.getWidth(); int height = bi.getHeight(); boolean flag = false; String result = ""; for (int i = 0; i < height; i += 2) { for (int j = 0; j < width; j++) { int pixel = bi.getRGB(j, i); // 下面三行程式碼將一個數字轉換為RGB數字 int red = (pixel & 0xff0000) >> 16; int green = (pixel & 0xff00) >> 8; int blue = (pixel & 0xff); float gray = 0.299f * red + 0.578f * green + 0.114f * blue; int index = Math.round(gray * (base.length() + 1) / 255); result += index >= base.length() ? " " : String.valueOf(base.charAt(index)); } result += "\r\n"; } flag = writeTxtFile(result,txtPath);//儲存字元到文字檔案 System.out.println(flag?"圖片轉字元儲存成功":"圖片轉字元儲存失敗"); } catch (Exception e) { System.out.println("圖片轉字元異常"+e.getMessage()); } } /** * 字元儲存到txt檔案中 * @param imageStr 字元 * @param txtPath txt檔案 * @return boolean * @throws Exception */ private static boolean writeTxtFile(String imageStr, String txtPath) throws Exception{ // 先讀取原有檔案內容,然後進行寫入操作 boolean flag = false; String filein = imageStr; String temp = ""; FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br = null; FileOutputStream fos = null; PrintWriter pw = null; try { // 檔案路徑 File file = new File(txtPath); if (!file.exists()) { file.createNewFile(); } // 將檔案讀入輸入流 fis = new FileInputStream(file); isr = new InputStreamReader(fis); br = new BufferedReader(isr); StringBuffer buf = new StringBuffer(); // 儲存該檔案原有的內容 for (int j = 1; (temp = br.readLine()) != null; j++) { buf = buf.append(temp); } buf.append(filein); fos = new FileOutputStream(file); pw = new PrintWriter(fos); pw.write(buf.toString().toCharArray()); pw.flush(); flag = true; } catch (IOException e) { System.out.println("檔案儲存失敗"+e.getMessage()); } finally { if (pw != null) { pw.close(); } if (fos != null) { fos.close(); } if (br != null) { br.close(); } if (isr != null) { isr.close(); } if (fis != null) { fis.close(); } } return flag; } }

非閃圖圖片轉字元畫返回BASE64

直接儲存為圖片也可以。

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import sun.misc.BASE64Encoder;

/**
 * Image2ASCII
 * @author 小帥丶
 * 2018年8月14日
 */
public class Image2ASCII{
	static String ascii = "
[email protected]
%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'."; static String base = "@#&$%*o!;.";//小帥丶使用這個字元 /** 圖片型別 */ private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_RGB; /** * 圖片轉字元再儲存為圖片 只返回圖片的base64 * @param bi 原圖 * @param outPutPath * @return String */ public static String txtToImageByBase64(BufferedImage bi) { System.out.println("進來的時間"+System.currentTimeMillis()); int width = bi.getWidth(); int height = bi.getHeight(); int minx = bi.getMinX(); int miny = bi.getMinY(); int speed = 7; BufferedImage bufferedImage = new BufferedImage(width,height,IMAGE_TYPE); // 獲取影象上下文 Graphics g = createGraphics(bufferedImage, width, height, speed); // 圖片中文字行高 final int Y_LINEHEIGHT = speed; int lineNum = 1; for (int i = miny; i < height; i += speed) { for (int j = minx; j < width; j += speed) { int pixel = bi.getRGB(j, i); // 下面三行程式碼將一個數字轉換為RGB數字 int red = (pixel & 0xff0000) >> 16; int green = (pixel & 0xff00) >> 8; int blue = (pixel & 0xff); float gray = 0.299f * red + 0.578f * green + 0.114f * blue; int index = Math.round(gray * (base.length() + 1) / 255); String c = index >= base.length() ? " " : String.valueOf(base.charAt(index)); g.drawString(String.valueOf(c), j, i); } lineNum++; } g.dispose(); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { ImageIO.write(bufferedImage,"jpg",out); BASE64Encoder base64Encoder = new BASE64Encoder(); String base64 =base64Encoder.encode(out.toByteArray()); return base64; } catch (IOException e) { System.out.println("ImageIO.write異常" + e.getMessage()); }finally{ if(null!=out){ try { out.close(); } catch (IOException e) { System.out.println("out.close()異常" + e.getMessage()); } } } return null; } /** * 畫板預設一些引數設定 * @param image 圖片 * @param width 圖片寬 * @param height 圖片高 * @param size 字型大小 * @return */ private static Graphics createGraphics(BufferedImage image, int width, int height, int size) { Graphics g = image.createGraphics(); g.setColor(null); // 設定背景色 g.fillRect(0, 0, width, height);// 繪製背景 g.setColor(Color.BLACK); // 設定前景色 g.setFont(new Font("微軟雅黑", Font.PLAIN, size)); // 設定字型 return g; } }

效果圖

方法返回的為圖片的base64資料。格式為jpg。加頭資訊即可在img標籤的src中顯示圖片哦。

線上轉base64為圖片 需要加頭資訊 data:image/jpg;base64,

閃圖圖片轉字元畫返回圖片

package com.xs.util.image;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;

import sun.misc.BASE64Encoder;

/**
 * Image2ASCII
 * @author 小帥丶
 * 2018年8月14日
 */
public class Image2ASCII{
	static String ascii = "[email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\\\"^`'.";
	static String base = "@#&$%*o!;.";//小帥丶使用這個字元
	 /** 圖片型別  */
    private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_RGB;
    /**
	 * gif圖片轉gif字元圖
	 * @param imagePath 原圖路徑
	 * @param outPath  輸出圖片的資料夾路徑
	 * @throws IOException
	 */
	public static void loadGif(String imagePath, String outPath)
			throws IOException {
		File imageFile = new File(imagePath);
		FileImageInputStream in = new FileImageInputStream(imageFile);
		ImageReaderSpi readerSpi = new GIFImageReaderSpi();
		GIFImageReader gifImageReader = new GIFImageReader(readerSpi);
		gifImageReader.setInput(in);
		int num = gifImageReader.getNumImages(true);
		System.out.println(num);
		BufferedImage[] bufferedImages = new BufferedImage[num];
		for (int i = 0; i < num; i++) {
			BufferedImage bi = gifImageReader.read(i);
			bufferedImages[i] = txtToImage(bi, outPath + "out" + i + ".jpeg"); //每一幀都儲存為圖片
		}
		jpgToGif(bufferedImages,outPath + imagePath.substring(imagePath.length() - 6)+ "outGif.gif", 200);
	}
	/**
	 * 圖片轉字元再儲存為圖片
	 * @param bi 原圖
	 * @param outPutPath
	 * @return BufferedImage
	 */
	public static BufferedImage txtToImage(BufferedImage bi, String outPutPath) {
		File imageFile = new File(outPutPath);
		if (!imageFile.exists()) {
			try {
				imageFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		int width = bi.getWidth();
		int height = bi.getHeight();
		int minx = bi.getMinX();
		int miny = bi.getMinY();
		System.out.println(width + " " + height);
		int speed = 7;
		BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		// 獲取影象上下文
		Graphics g = createGraphics(bufferedImage, width, height, speed);
		// 圖片中文字行高
		final int Y_LINEHEIGHT = speed;
		int lineNum = 1;
		for (int i = miny; i < height; i += speed) {
			for (int j = minx; j < width; j += speed) {
				int pixel = bi.getRGB(j, i); // 下面三行程式碼將一個數字轉換為RGB數字
				int red = (pixel & 0xff0000) >> 16;
				int green = (pixel & 0xff00) >> 8;
				int blue = (pixel & 0xff);
				float gray = 0.299f * red + 0.578f * green + 0.114f * blue;
				int index = Math.round(gray * (base.length() + 1) / 255);
//				char c = ascii.charAt((int) (gray / 255 * ascii.length()));
//				char c = toChar((int) gray);
//				char c = toChar(index);
				String c = index >= base.length() ? " " : String.valueOf(base.charAt(index));
				g.drawString(String.valueOf(c), j, i);
			}
			lineNum++;
		}
		g.dispose();
		// 儲存為jpg圖片
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(imageFile);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
			OutputStream out = encoder.getOutputStream();
		    BASE64Encoder base64Encoder = new BASE64Encoder();
			encoder.encode(bufferedImage);
			fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ImageFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bufferedImage;

	}
	/**
	 * 畫板預設一些引數設定
	 * @param image 圖片
	 * @param width 圖片寬
 	 * @param height 圖片高
	 * @param size 字型大小
	 * @return
	 */
	private static Graphics createGraphics(BufferedImage image, int width,
			int height, int size) {
		Graphics g = image.createGraphics();
		g.setColor(null); // 設定背景色
		g.fillRect(0, 0, width, height);// 繪製背景
		g.setColor(Color.BLACK); // 設定前景色
		g.setFont(new Font("微軟雅黑", Font.PLAIN, size)); // 設定字型
		return g;
	}
	/**
	 * n張jpg轉gif方法  
	 * @param bufferedImages
	 * @param newPic
	 * @param playTime
	 */
	private static void jpgToGif(BufferedImage[] bufferedImages, String newPic,
			int playTime) {
		try {
			AnimatedGifEncoder e = new AnimatedGifEncoder();
			e.setRepeat(0);
			e.start(newPic);
			for (int i = 0; i < bufferedImages.length; i++) {
				e.setDelay(playTime); // 設定播放的延遲時間
				e.addFrame(bufferedImages[i]); // 新增到幀中
			}
			e.finish();
		} catch (Exception e) {
			System.out.println("jpgToGif Failed:");
		}
	}
}

呼叫程式碼

public static void main(String[] args) throws Exception {
		loadGif("C:/Users/Administrator/Desktop/頁面錄屏顯示.gif", "F:/gif/");//動圖轉為動態的字元圖片
	}

返回的圖片效果原圖為小程式演示閃圖