java 读取图片色深
问题:
想写一个小程序可读取图片的色深(bit-depth)。网上有一些软件可完成这个功能,但是我想把程序做成一个可移植的插件。
本想用c写的,但实在麻烦,最后选择java,与很多方法不用自己写,速度快。
最后打包成一个jar包,只要装了jdk就可以在控制台运行。
我用的是MYECLIPSE,步骤如下:
1.创建一个工程;
2.创建一个java class;
3.程序包含两个类getinfo.java 和 methodclass.java;
getinfo.java包含main()方法,代码如下:
import java.io.File; public class getinfo { public static void main(String[] args) { // TODO Auto-generated method stub String url; if (args.length != 0) { url = args[0]; } else url = "F:\\tmpxu\\333.png"; File f1 = new File(url);// "F:\\tmpxu\\333.png" methodclass my = new methodclass(); my.ImageInfo(f1); System.out.println("getName====" + my.getName()); System.out.println("getPath====" + my.getPath()); System.out.println("getDate_created====" + my.getDate_created()); System.out.println("getDate_modified====" + my.getDate_modified()); System.out.println("getType====" + my.getType()); System.out.println("getSize====" + my.getSize()); System.out.println("getWidth====" + my.getWidth()); System.out.println("getHeight====" + my.getHeight()); System.out.println("getBit_depth====" + my.getBit_depth()); } }
这里注意:
控制台命令: java -jar getImageInfo.jar 参数1 参数2 参数3……
其中getImageInfo.jar为最终生成的jar包,参数1 参数2 参数3……可作为main(String args[])的参数,从String args[]中得到。
methodclass.java类主要完成具体的读取图片信息的方法,支持png 、jpeg 、gif 、bmp格式。
代码大多来自这个链接:http://yuncode.net/code/c_53881eaa2532066,整理后的代码如下:
import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.StringTokenizer; import javax.imageio.ImageIO; public class methodclass { private String name = ""; private String path = ""; private String date_created = ""; private String date_modified = ""; private String bytes = ""; private String type = ""; private String size = ""; private String width = ""; private String height = ""; private String bit_depth = ""; public void ImageInfo(File file) { name = file.getName(); path = file.getParent(); date_created = getDate_created(file); date_modified = new SimpleDateFormat("yyyy/MM/dd HH:mm") .format(new Date(file.lastModified())); bytes = getBytes(file); getImageData(file); getImageFileData(file); } // 判读图片类型 private void getImageFileData(File file) { try { FileInputStream input = new FileInputStream(file); /* * he java.io.FileInputStream.available() method returns number of * remaining bytes that can be read from this input stream without * blocking by the next method call for this input stream. The next * method call can also be the another thread. * 通过available方法取得流的最大字符数 */ byte[] b = new byte[input.available()]; if (b.length == 0) { System.out.print("the file is empty!!!"); return; } input.read(b); input.close(); int b1 = b[0] & 0xff; int b2 = b[1] & 0xff; if (b1 == 0x42 && b2 == 0x4d) { checkBmp(b); } else if (b1 == 0x47 && b2 == 0x49) { checkGif(b); } else if (b1 == 0x89 && b2 == 0x50) { checkPng(b); } else if (b1 == 0xff && b2 == 0xd8) { checkJpeg(b, file); } } catch (IOException e) { e.printStackTrace(); } } // 获得图片宽高 private void getImageData(File file) { try { BufferedImage img = ImageIO.read(file); size = img.getWidth() + " x " + img.getHeight(); width = img.getWidth() + " 像素"; height = img.getHeight() + " 像素"; } catch (IOException e) { e.printStackTrace(); } } public void checkBmp(byte[] b) { type = "BMP 文件"; int bitsPerPixel = (b[28] & 0xff) | (b[29] & 0xff) << 8; if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8 || bitsPerPixel == 16 || bitsPerPixel == 24 || bitsPerPixel == 32) { bit_depth = bitsPerPixel + ""; } } public void checkGif(byte[] b) { type = "GIF 文件"; bit_depth = (b[10] & 0x07) + 1 + ""; } public void checkPng(byte[] b) { type = "PNG 图像"; int bitsPerPixel = b[24] & 0xff; if ((b[25] & 0xff) == 2) { bitsPerPixel *= 3; } else if ((b[25] & 0xff) == 6) { bitsPerPixel *= 4; } bit_depth = bitsPerPixel + ""; } /* * (b[i] & 0xff):byte转换int时的运算 其原因在于:1.byte的大小为8bits而int的大小为32bits; * 2.java的二进制采用的是补码形式; * 如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位, * 例如补码11111111的十进制数为-1转换为int时变为32个1!和0xff相与后,高24比特就会被清0了,结果就对了。 bit_depth: * a 1 bit image, can only show two colors, black and white. That is because * the 1 bit can only store one of two values, 0 (white) and 1 (black). An 8 * bit image can store 256 possible colors, while a 24 bit image can display * about 16 million colors. */ public void checkJpeg(byte[] b, File file) { type = "JPEG 图像"; int i = 2; while (true) { int marker = (b[i] & 0xff) << 8 | (b[i + 1] & 0xff); int size = (b[i + 2] & 0xff) << 8 | (b[i + 3] & 0xff); if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) { bit_depth = (b[i + 4] & 0xff) * (b[i + 9] & 0xff) + ""; break; } else { i += size + 2; } } } // 文件创建日期 private String getDate_created(File file) { try { Process ls_proc = Runtime.getRuntime().exec( "cmd.exe /c dir \"" + file.getAbsolutePath() + "\" /tc"); BufferedReader reader = new BufferedReader(new InputStreamReader( ls_proc.getInputStream())); for (int i = 0; i < 5; i++) { reader.readLine(); } StringTokenizer st = new StringTokenizer(reader.readLine()); String date = st.nextToken(); String time = st.nextToken(); reader.close(); return date + " " + time; } catch (IOException e) { e.printStackTrace(); } return ""; } // 读取文件大小 private String getBytes(File file) { DecimalFormat df = new DecimalFormat(); float length = (float) file.length(); int p = 0; while (length > 1023) { length /= 1024; p++; } if (length > 99) { df.setMaximumFractionDigits(0); } else if (length > 9) { df.setMaximumFractionDigits(1); } else { df.setMaximumFractionDigits(2); } if (p == 0) { return (int) length + " 字节"; } else if (p == 1) { return df.format(length) + " KB"; } else if (p == 2) { return df.format(length) + " MB"; } else if (p == 3) { return df.format(length) + " GB"; } else { return df.format(length) + " TB"; } } public String getName() { return name; } public String getPath() { return path; } public String getDate_created() { return date_created; } public String getDate_modified() { return date_modified; } public String getBytes() { return bytes; } public String getType() { return type; } public String getSize() { return size; } public String getWidth() { return width; } public String getHeight() { return height; } public String getBit_depth() { return bit_depth; } }
1.生成jar包:生成jar包时,程序不能有错误、不能有警告,编译通过后可export,我这里jar包命名为getImageInfo.jar;
2.控制台运行jar包,命令如下图:
注意:
1.路径f:\\tmpxu\\222.jpg 必须两个“\”。
2.window里切换路径和linux不同,不能直接用cd,先切换到f盘,直接输入“f:”命令,回车;
然后cd 到目标目录即可。
3.执行jar包用java -jar file.jar 命令;
最后得到色深为8;