zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    charindex代替like并非"更快更全面"
    SQLServer2005中的几个统计技巧
    SQLServer获取Excel中所有Sheet
    SQLServer2005的查询独占模拟
    SSAS事实表和维度表数据类型必须一致
    monodevelop 出现has line endings which differ from the policy settings.的解决方法
    mono for android Main.axml
    vs2010 错误提示框:文件加载 使用 简体中文(GB2312
    在Virtual Machine上运行Hello China的方法和工具
    embed基本语法
  • 原文地址:https://www.cnblogs.com/McQueen1987/p/4074055.html
Copyright © 2011-2022 走看看