图片加盲水印的工具类

package pictureHideEncryption;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;


import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

import static org.opencv.highgui.Highgui.imwrite;
import static org.opencv.highgui.Highgui.imread;


public class test10 {  
    private static List<Mat> planes;  
    private static Mat complexImage;  
    List<Mat> images = new ArrayList<Mat>();
    
    private test10(){}  
    private static final test10 dftUtil = new test10();
  
    public static test10 getInstance () {  
        planes = new ArrayList<Mat>();  
        complexImage = new Mat();  
        return dftUtil;  
    }  
    
    public static void clearMemory(){
        
    }
    
    
    public Mat transformImage(Mat image) {  
        // planes数组中存的通道数若开始不为空,需清空.  
        if (!planes.isEmpty()) {  
            planes.clear();  
        }  
        // optimize the dimension of the loaded image  
        Mat padded = this.optimizeImageDim(image);  
        padded.convertTo(padded, CvType.CV_32F);  
        // prepare the image planes to obtain the complex image  
        planes.add(padded);  
        
        planes.add(Mat.zeros(padded.size(), CvType.CV_32F));  
        
        // prepare a complex image for performing the dft  
        Core.merge(planes, complexImage);  
        // dft  
        Core.dft(complexImage, complexImage);  
        // optimize the image resulting from the dft operation  
        Mat magnitude = this.createOptimizedMagnitude(complexImage);  
        planes.clear(); 
        padded.release();
        image.release();
        return magnitude;  
    }  
    
    public void transformImageWithText(Mat image, String watermarkText, Point point, Double fontSize, Scalar scalar) {  
        // planes数组中存的通道数若开始不为空,需清空.  
        if (!planes.isEmpty()) {  
            planes.clear();  
        }  
        if (!images.isEmpty()) {  

             //释放内存

            for (Mat mat : images) {
                mat.release();
            }
            images.clear();  
        } 
        // optimize the dimension of the loaded image  
        Mat padded = this.optimizeImageDim(image);  
        //Mat padded = image;    
        padded.convertTo(padded, CvType.CV_32F);  
//        // prepare the image planes to obtain the complex image  
//        planes.add(padded);  
//        planes.add(Mat.zeros(padded.size(), CvType.CV_32F));  
//        // prepare a complex image for performing the dft  
//        Core.merge(planes, complexImage);  
        
        
        images.add(Mat.zeros(padded.size(), CvType.CV_8U));  
        Core.split(padded, images);//RGB通道分离
//        Mat mat0=images.get(0);//获得第二通道分量
//        Mat mat1=images.get(1);//获得第二通道分量
//        Mat mat2=images.get(2);//获得第二通道分量
        
//        imwrite("F:/JPGReachBMP/a/1.png", mat0);
//        imwrite("F:/JPGReachBMP/a/2.png", mat1);
//        imwrite("F:/JPGReachBMP/a/3.png", mat2);
        
        Core.dft(images.get(0), images.get(0));  
        Core.dft(images.get(1), images.get(1));  
        Core.dft(images.get(2), images.get(2));    

        
        Core.merge(images,complexImage);//RGB通道合并

        // dft  
        //Core.dft(complexImage, complexImage);         
        // 频谱图上添加文本  
        Core.putText(complexImage, watermarkText, point, Core.FONT_HERSHEY_DUPLEX, fontSize, scalar,2);  
        Core.flip(complexImage, complexImage, -1);  
        Core.putText(complexImage, watermarkText, point, Core.FONT_HERSHEY_DUPLEX, fontSize, scalar,2);  
        Core.flip(complexImage, complexImage, -1);  
        planes.clear();  
        padded.release();
        image.release();
    }  
    Mat invDFT0 = new Mat();  
    Mat invDFT1 = new Mat(); 
    Mat invDFT2 = new Mat(); 
    public Mat antitransformImage() {  
        if (!images.isEmpty()) {  
            images.clear();  
        } 
        
        Core.split(complexImage, images);//RGB通道分离
        
        Core.idft(images.get(0), invDFT0, Core.DFT_SCALE | Core.DFT_REAL_OUTPUT, 0); 
        Core.idft(images.get(1), invDFT1, Core.DFT_SCALE | Core.DFT_REAL_OUTPUT, 0); 
        Core.idft(images.get(2), invDFT2, Core.DFT_SCALE | Core.DFT_REAL_OUTPUT, 0); 
      
        //Core.idft(complexImage, invDFT, Core.DFT_SCALE | Core.DFT_REAL_OUTPUT, 0);   
        invDFT0.convertTo(images.get(0), CvType.CV_8U);  
        invDFT1.convertTo(images.get(1), CvType.CV_8U); 
        invDFT2.convertTo(images.get(2), CvType.CV_8U); 
        Core.merge(images,complexImage);//RGB通道合并
        planes.clear();
        invDFT0.release();
        invDFT1.release();
        invDFT2.release();
        return complexImage;  
    }  
  
    /** 
     * 为加快傅里叶变换的速度,对要处理的图片尺寸进行优化 
     *  
     * @param image 
     *            the {@link Mat} to optimize 
     * @return the image whose dimensions have been optimized 
     */  
    Mat paddedoptimize = new Mat();
    private Mat optimizeImageDim(Mat image) {  
        // init  
          
        // get the optimal rows size for dft  
//        int addPixelRows = Core.getOptimalDFTSize(image.rows());  
        // get the optimal cols size for dft  
//        int addPixelCols = Core.getOptimalDFTSize(image.cols());  
        // apply the optimal cols and rows size to the image  
//        Imgproc.copyMakeBorder(image, padded, 0, addPixelRows - image.rows(), 0, addPixelCols - image.cols(),  
//                Imgproc.BORDER_CONSTANT, Scalar.all(0)); 
        Imgproc.copyMakeBorder(image, paddedoptimize, 0, 0, 0, 0, Imgproc.BORDER_CONSTANT, Scalar.all(0)); 
        image.release();
        return paddedoptimize;  
    }  
  
    /** 
     * Optimize the magnitude of the complex image obtained from the DFT, to 
     * improve its visualization 
     *  
     * @param complexImage 
     *            the complex image obtained from the DFT 
     * @return the optimized image 
     */ 
    List<Mat> newPlanes = new ArrayList();
    private Mat createOptimizedMagnitude(Mat complexImage) {  
        // init  
        if (!newPlanes.isEmpty()) {  
            newPlanes.clear();  
        } 
        Mat mag = new Mat();  
        // split the comples image in two planes  
        Core.split(complexImage, newPlanes);  
        // compute the magnitude  
        Core.magnitude(newPlanes.get(0), newPlanes.get(1), mag);  
  
        // move to a logarithmic scale  
        Core.add(Mat.ones(mag.size(), CvType.CV_32F), mag, mag);  
        Core.log(mag, mag);  
        // optionally reorder the 4 quadrants of the magnitude image  
        this.shiftDFT(mag);  
        // normalize the magnitude image for the visualization since both JavaFX  
        // and OpenCV need images with value between 0 and 255  
        // convert back to CV_8UC1  
        mag.convertTo(mag, CvType.CV_8UC1);
        Core.normalize(mag, mag, 0, 255, Core.NORM_MINMAX, CvType.CV_8UC1);  
        return mag;  
    }  
  
    /** 
     * Reorder the 4 quadrants of the image representing the magnitude, after 
     * the DFT 
     *  
     * @param image 
     *            the {@link Mat} object whose quadrants are to reorder 
     */  
    Mat q0 = null;
    Mat q1 = null;
    Mat q2 = null;
    Mat q3 = null;
    Mat tmp = null;
    private void shiftDFT(Mat image) {  
        image = image.submat(new Rect(0, 0, image.cols() & -2, image.rows() & -2));  
        int cx = image.cols() / 2;  
        int cy = image.rows() / 2;  
  
        q0 = new Mat(image, new Rect(0, 0, cx, cy));  
        q1 = new Mat(image, new Rect(cx, 0, cx, cy));  
        q2 = new Mat(image, new Rect(0, cy, cx, cy));  
        q3 = new Mat(image, new Rect(cx, cy, cx, cy));  
  
        tmp = new Mat();  
        q0.copyTo(tmp);  
        q3.copyTo(q0);  
        tmp.copyTo(q3);  
  
        q1.copyTo(tmp);  
        q2.copyTo(q1);  
        tmp.copyTo(q2);  
        
        q0.release();
        q1.release();
        q2.release();
        q3.release();
        tmp.release();
    }  

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值