添加水印后生成的图片模糊:设置属性 RenderingHints

版权声明: https://blog.csdn.net/qq_36907589/article/details/88183193
package com.jeecg.prize.controller;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;

public class ImageTextTest {

    public void addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent, Color markContentColor){
        Font font = new Font("微软雅黑", Font.PLAIN, 38);
        try{
            File srcImageFile = new File(srcImgPath);
            Image srcImg = ImageIO.read(srcImageFile);//文件转化为图片
            int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
            int srcImgHeight = srcImg.getHeight(null);//获取图片的高

            //加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight,             
                  BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            g.setColor(markContentColor);
            g.setFont(font);
            Graphics2D gPhone = bufImg.createGraphics();

            gPhone.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            gPhone.setColor(markContentColor);
            gPhone.setFont(font);
            String markContent = "张三三";
            AttributedString ats = new AttributedString(markContent);

            ats.addAttribute(TextAttribute.FONT, font, 0, markContent.length());
            AttributedCharacterIterator name = ats.getIterator();
            g.drawString(name, 150, 255);  //画出水印
            g.dispose();

            font = new Font("微软雅黑", Font.PLAIN, 26);
            gPhone.setColor(markContentColor);
            gPhone.setFont(font);
            RenderingHints rh=new RenderingHints(RenderingHints. KEY_ANTIALIASING,
                    RenderingHints. VALUE_ANTIALIAS_ON);
            rh.put(RenderingHints.KEY_STROKE_CONTROL
                    , RenderingHints.VALUE_STROKE_PURE);
            rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
                    , RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            gPhone.setRenderingHints(rh);
            gPhone.drawString("198-0395-****",125,330);
            gPhone.drawString("[email protected]",123,390);
            gPhone.drawString("www.*****.com",127,449);
            gPhone.drawString("河南省漯河市xxxxx55号",127,512);
            gPhone.dispose();


            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufImg, "png", outImgStream);
            System.out.println("添加水印完成");
            outImgStream.flush();
            outImgStream.close();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    public int getWatermarkLength(String waterMarkContent,Graphics2D g){
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }

    public static  void main(String[] args) {

      
        String srcImgPath="D:/mmm.jpg";  //源图片地址
        String tarImgPath="D:/aaa.png"; //待存储的地址
        String waterMarkContent="mm";  //水印内容(无效)
        new ImageTextTest().addWaterMark(srcImgPath, tarImgPath, waterMarkContent,Color.black);
    }
    }

RenderingHints 类定义了多种着色微调,它们存储在一个映射集的 Graphics2D 对象里。setRenderingHint() 方法的参数是一个键以及对应的键值。在我们的代码中,第一个参数是代表 alpha 合成微调的键,第二个参数是该微调的值。该微调的其它可能的值有 VALUE_ALPHA_INTERPOLATION_DEFAULT,代表平台缺省值;以及 VALUE_ALPHA_INTERPOLATION_SPEED,代表追求速度而不是质量。

  您还可以为下面的键提供微调:

  键描述KEY_ANTIALIASING决定是否使用抗锯齿。当着色有倾斜角度的线时,通常会得到一组阶梯式的像素排列,使这条线看上去不平滑,经常被称为 锯齿状图形抗锯齿是一种技术,它设置有倾斜角度的线的像素亮度,以使线看起来更平滑。因此,这个微调是用来决定在着色有倾斜角度的线时是否在减少锯齿状图形上花费时间。可能的值有 VALUE_ANTIALIAS_ON, _OFF 或 _DEFAULT。KEY_COLOR_RENDERING控制颜色着色的方式。可能的值有 VALUE_COLOR_RENDER_SPEED, _QUALITY 或 _DEFAULT。KEY_DITHERING控制如何处理抖动。抖动是用一组有限的颜色合成出一个更大范围的颜色的过程,方法是给相邻像素着色以产生不在该组颜色中的新的颜色幻觉。可能的值有 VALUE_DITHER_ENABLE, _DISABLE 或 _DEFAULT。KEY_FRACTIONALMETRICS控制显示文本的质量。可能的值有 VALUE_FRACTIONALMETRICS_ON, _OFF 或 _DEFAULT。KEY_INTERPOLATION确定怎样做内插。
  
  在对一个源图像做变形时,变形后的像素很少能够恰好对应目标像素位置。在这种情况下,每个变形后的像素的颜色值不得不由四周的像素决定。
  
  内插就是实现上述过程。有许多可用的技术。可能的值,按处理时间从最多到最少,是 VALUE_INTERPOLATION_BICUBIC, _BILINEAR 或 _NEAREST_NEIGHBOR。KEY_RENDERING确定着色技术,在速度和质量之间进行权衡。可能的值有 VALUE_RENDERING_SPEED, _QUALITY 或 _DEFAULT。KEY_TEXT_ANTIALIASING确定对文本着色时是否抗锯齿。可能的值有 VALUE_TEXT_ANTIALIASING_ON, _OFF 或 _DEFAULT

使用java.awt.RenderingHints类设置参数,改善图片质量

如果想设置几个呈现提示(RenderingHints),可以多次调用setRenderHint,或者创建值的完整映射,并使用Graphics2D的setRenderingHints方法一次把它们都设置好。

java.awt.RenderingHints类 javadoc文档连接:
http://gceclub.sun.com.cn/Java_Docs/jdk6/docs/zh/api/java/awt/RenderingHints.html

一般使用的代码如下:

RenderingHints rh=new RenderingHints(RenderingHints. KEY_ANTIALIASING,
                                                        RenderingHints. VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_STROKE_CONTROL
              , RenderingHints.VALUE_STROKE_PURE);
rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
              , RenderingHints.ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHints(rh);

找出一个给定系统的方法是判断特定的绘制硬件(比如显卡)在系统中是否可用,假设有一个假想的isAccelerated方法告诉系统是否可以使用一种类型的图像加速。下面的代码允许根据isAccelerated方法的结果来设置提示:
//假设renderQuality是RenderingHints的私有类成员
if(isAccelerated()){
       renderQuality=new RenderingHints(RenderingHints. KEY_RENDERING, 
                                                               RenderingHints. VALUE_RENDER_QUALITY);
}else{
       renderQuality=new RenderingHints(RenderingHints. KEY_RENDERING, 
                                                               RenderingHints. VALUE_RENDER_SPEED);
}


这样设置后比没有设置效果会好点。但是和acdsee等图片工具看起来还有差距。比较奇怪还需要设置什么参数才能优化图片质量。。。

另外,关于性能今天看到的一篇文章有点作用。。
现在图片预览一样存在Jprofile的大量内存使用的问题.
看到javatar的blog: http://javatar.javaeye.com/blog/41098
提及使用第三方的包 JMagicK: http://www.yeo.id.au/jmagick/ (Java接口)(转载)

猜你喜欢

转载自blog.csdn.net/qq_36907589/article/details/88183193