添加水印後生成的圖片模糊:設置屬性 RenderingHints

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接口)(轉載)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章