綦霖
好记性不如烂笔头~ 持续写bug中...

周五收到说要做一个给照片加水印的功能,大概就是说将一张含有坐标点的图片,将它的坐标点以及拍摄时间给打印在照片上,于是乎就在网上找了些相关文章,一开始不太顺利,图片根本解析不出来东西还报了一堆的错,开始还以为是代码的问题,就在那找啊找测啊测的,后来才发现是依赖的jar没导全,以及开发工具设置的一些问题。

其实这个功能分两步,

一、将图片(必须是带有位置信息的照片)里含有的信息解析出来:

   

package photo;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

import javax.swing.ImageIcon;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * java读取照片信息
 */
public class SampleUsage {
    public static void main(String[] args) throws Exception, Exception {
        File file = new File("D:\\test\\aa.jpg");
        printImageTags(file);
    }

    /**
     * 读取照片里面的信息
     */
    private static void printImageTags(File file) throws ImageProcessingException, Exception {
        Metadata metadata = ImageMetadataReader.readMetadata(file);
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                String tagName = tag.getTagName(); // 标签名
                String desc = tag.getDescription(); // 标签信息
                if (tagName.equals("Image Height")) {
                    System.out.println("图片高度: " + desc);
                } else if (tagName.equals("Image Width")) {
                    System.out.println("图片宽度: " + desc);
                } else if (tagName.equals("Date/Time Original")) {
                    System.out.println("拍摄时间1: " + desc);
                }else if (tagName.equals("Date/Time Digitized")) {
                    System.out.println("拍摄时间2: " + desc);
                } else if (tagName.equals("GPS Latitude")) {
                    System.err.println("纬度 : " + desc);
                    System.err.println("纬度(度分秒格式) : " + pointToLatlong(desc));
                } else if (tagName.equals("GPS Longitude")) {
                    System.err.println("经度: " + desc);
                    System.err.println("经度(度分秒格式): " + pointToLatlong(desc));
                }
                System.err.println("tagName: " + tagName+"----->desc"+desc);
            }
        }
    }


    /**
     * 经纬度格式 转换为 度分秒格式 ,如果需要的话可以调用该方法进行转换
     * 
     * @param point
     *            坐标点
     * @return
     */
    public static String pointToLatlong(String point) {
        Double du = Double.parseDouble(point.substring(0, point.indexOf("°")).trim());
        Double fen = Double.parseDouble(point.substring(point.indexOf("°") + 1, point.indexOf("'")).trim());
        Double miao = Double.parseDouble(point.substring(point.indexOf("'") + 1, point.indexOf("\"")).trim());
        Double duStr = du + fen / 60 + miao / 60 / 60;
        return duStr.toString();
    }
}

 

运行结果就如下:

    

 

 

ps:需要注意得是查看一张图片是否含有位置信息,找到图片鼠标右键点击“属性”-->“详细信息” 如下:

        

 

 二、就是将第一步解析到的信息拿到你想要的,并将它打印在照片上:

package photo;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import javax.swing.ImageIcon;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
 
public class ImageEdit {
    
    public static void main(String[] a) {
 
 
        ImageEdit.createStringMark("D:\\test\\photo\\IMG_954.jpg", "*****测试文字*****","D:\\test\\B.jpg");
        }
 
 
       /**
         * @param filePath 源图片路径
         * @param markContent 图片中添加内容
         * @param outPath  输出图片路径
         * 字体颜色等在函数内部实现的
       */
        //给jpg添加文字
        public static boolean createStringMark(String filePath,String markContent,String outPath) 
        { 
        ImageIcon imgIcon=new ImageIcon(filePath); 
        Image theImg =imgIcon.getImage(); 
        int width=theImg.getWidth(null)==-1?200:theImg.getWidth(null); 
        int height= theImg.getHeight(null)==-1?200:theImg.getHeight(null); 
        System.out.println(width);
        System.out.println(height);
        System.out.println(theImg.toString());
        BufferedImage bimage = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); 
        Graphics2D g=bimage.createGraphics(); 
        
        Color mycolor = Color.red; 
        g.setColor(mycolor); 
        g.setBackground(Color.red); 
        g.drawImage(theImg, 0, 0, null ); 
        g.setFont(new Font("宋体",Font.PLAIN,80)); //字体、字型、字号 
        g.drawString(markContent,width/80,height-height/100); //画文字 
        g.dispose(); 
        try 
        { 
        FileOutputStream out=new FileOutputStream(outPath); //先用一个特定的输出文件名 
        JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(out); 
        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage); 
        param.setQuality(100, true);  //
        encoder.encode(bimage, param); 
        out.close(); 
        } 
        catch(Exception e) 
        { return false; } 
        return true; 
        } 
 
}

测试结果:

  因为我的需求是将解析的信息加在照片的下方(关于字体、颜色、位置都可以设置),所以:

  

 

 看起来是大功告成了呢,哈哈。再顺便排个雷,以下我再将用到的jjar包和eclipse设置告诉一下,话不多数上截图

    

这两个jar缺一不可的,jar包的话可以去

   https://mvnrepository.com/artifact/com.drewnoakes/metadata-extractor/2.6.2

   https://mvnrepository.com/artifact/com.adobe.xmp/xmpcore/5.1.2 

 里下载这两个,在文件类型里选择jar还是pom

  

 

如果eclipse(MyEclipse同理)在打印照片时,引入的

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
报错的话:
Access restriction: The type JPEGImageEncoder is not accessible due to restriction on required library C:\Java\jre1.6.0_07\lib\rt.jar


此时解决办法:
Eclipse默认把这些受访问限制的API设成了ERROR。只要把Windows-Preferences-Java-Complicer-Errors/Warnings里面的Deprecated and restricted API中的Forbidden references(access rules)选为Warning就可以编译通过。

 

 

 

最后的最后,将这两个合二为一,我需要的是拍摄时间以及经纬度,那么以下:

  


/**
 * @author yc  
 * @date 2019年3月8日 
 */
package photo;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

import javax.swing.ImageIcon;

public class ExifTester {

    public static void main(String[] args) throws ImageProcessingException, Exception {
        File file = new File("D:\\test\\photo\\IMG_954.jpg");
        if(file.exists()){
            String imageMsg = printImageTags(file);
            boolean result = ImageEdit.createStringMark(file.getPath(), imageMsg,"D:\\test\\B.jpg");
            System.out.println("iamgeMsg:----->" + imageMsg+"打印到照片上:"+result);
        }else{
            System.out.println("图片不存在或错误,请核实!");
        }
    }

    /**
     * 读取照片里面的信息
     */
    private static String printImageTags(File jpegFile) throws ImageProcessingException, Exception {
        //File jpegFile = new File(filePath);
        Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
        String imageToString = "";
        imagesEntity image = new imagesEntity();
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                // System.out.print("name : " + tag.getTagName() + "  -->");
                // System.out.println("desc : " + tag.getDescription());

                String tagName = tag.getTagName();
                String desc = tag.getDescription();

                if (tagName.equals("Image Height")) {
                    System.out.println("图片高度: " + desc);
                } else if (tagName.equals("Image Width")) {
                    System.out.println("图片宽度: " + desc);
                } else if (tagName.equals("Date/Time Original")) {
                    image.setDateOriginal(desc);
                    System.out.println("拍摄时间1: " + desc);
                } else if (tagName.equals("Date/Time Digitized")) {
                    image.setDateDigitized(desc);
                    System.out.println("拍摄时间2: " + desc);
                } else if (tagName.equals("GPS Latitude")) {
                    System.err.println("纬度 : " + desc);
                    image.setLatitude(pointToLatlong(desc));
                    System.err.println("纬度(度分秒格式) : " + pointToLatlong(desc));
                } else if (tagName.equals("GPS Longitude")) {
                    System.err.println("经度: " + desc);
                    image.setLongitude(pointToLatlong(desc));
                    System.err.println("经度(度分秒格式): " + pointToLatlong(desc));
                }
            }
        }
        imageToString = image.getLongitude() + "," + image.getLatitude() + "  " + image.getDateOriginal();
        System.err.println("照片内获取信息为" + imageToString);
        return imageToString;
    }

    /**
     * 经纬度格式 转换为 度分秒格式 ,如果需要的话可以调用该方法进行转换
     * 
     * @param point
     *            坐标点
     * @return
     */
    public static String pointToLatlong(String point) {
        Double du = Double.parseDouble(point.substring(0, point.indexOf("°")).trim());
        Double fen = Double.parseDouble(point.substring(point.indexOf("°") + 1, point.indexOf("'")).trim());
        Double miao = Double.parseDouble(point.substring(point.indexOf("'") + 1, point.indexOf("\"")).trim());
        Double duStr = du + fen / 60 + miao / 60 / 60;
        return duStr.toString();
    }
    /**
     * @param filePath 源图片路径
     * @param markContent 图片中添加内容
     * @param outPath  输出图片路径
     * 字体颜色等在函数内部实现的
   */
    //给jpg添加文字
    public static boolean createStringMark(String filePath,String markContent,String outPath) 
    { 
    ImageIcon imgIcon=new ImageIcon(filePath); 
    Image theImg =imgIcon.getImage(); 
    int width=theImg.getWidth(null)==-1?200:theImg.getWidth(null); 
    int height= theImg.getHeight(null)==-1?200:theImg.getHeight(null); 
    System.out.println(width);
    System.out.println(height);
    System.out.println(theImg.toString());
    BufferedImage bimage = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g=bimage.createGraphics(); 
    
    Color mycolor = Color.red; 
    g.setColor(mycolor); 
    g.setBackground(Color.red); 
    g.drawImage(theImg, 0, 0, null ); 
    g.setFont(new Font("宋体",Font.PLAIN,80)); //字体、字型、字号 
    g.drawString(markContent,width/80,height-height/100); //画文字位置 
    g.dispose(); 
    try 
    { 
    FileOutputStream out=new FileOutputStream(outPath); //先用一个特定的输出文件名 
    JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(out); 
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage); 
    param.setQuality(100, true);  //
    encoder.encode(bimage, param); 
    out.close(); 
    } 
    catch(Exception e) 
    { return false; } 
    return true; 
    } 
}

信息实体:

  

/**
 * @author yc  
 * @date 2019年3月8日 
 */
package photo;

/**
 * @author yang.cheng  
 * @date 2019年3月8日 
 */
public class imagesEntity {
    private String DateOriginal;
    private String DateDigitized;
    private String Latitude;
    private String Longitude;
    public String getDateOriginal() {
        return DateOriginal;
    }
    public void setDateOriginal(String dateOriginal) {
        DateOriginal = dateOriginal;
    }
    public String getDateDigitized() {
        return DateDigitized;
    }
    public void setDateDigitized(String dateDigitized) {
        DateDigitized = dateDigitized;
    }
    public String getLatitude() {
        return Latitude;
    }
    public void setLatitude(String latitude) {
        Latitude = latitude;
    }
    public String getLongitude() {
        return Longitude;
    }
    public void setLongitude(String longitude) {
        Longitude = longitude;
    }
    @Override
    public String toString() {
        return "imagesEntity [DateOriginal=" + DateOriginal + ", DateDigitized=" + DateDigitized + ", Latitude=" + Latitude + ", Longitude="
                + Longitude + "]";
    }
    

}

 

posted on 2019-03-11 14:16  綦霖  阅读(1238)  评论(3编辑  收藏  举报