KKSU
2024-05-30 84599f1fdac0d9723c7f02a2e66b0e909ad911d7
图片上传
7 files modified
1746 ■■■■ changed files
pom.xml 10 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/test/DYDelMark.java 324 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/test/FingerPrint.java 634 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/test/ImageToChar.java 292 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/test/PixelateImage.java 190 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/test/getGray.java 102 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/test/imageTest.java 194 ●●●● patch | view | raw | blame | history
pom.xml
@@ -29,11 +29,11 @@
    <dependencies>
        <dependency>
            <groupId>com.madgag</groupId>
            <artifactId>animated-gif-lib</artifactId>
            <version>1.4</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>com.madgag</groupId>-->
<!--            <artifactId>animated-gif-lib</artifactId>-->
<!--            <version>1.4</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.web3j</groupId>
src/main/java/cc/mrbird/febs/mall/test/DYDelMark.java
@@ -1,162 +1,162 @@
package cc.mrbird.febs.mall.test;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DYDelMark {
    public static void main(String[] args) {
        String content = "https://v.douyin.com/iLwxgYHE/";
        JSONObject douYData = extractDouYinData(content);
        if (douYData != null) {
            System.out.println(douYData);
        } else {
            System.out.println(1);
        }
    }
    private static JSONObject extractDouYinData(String content) {
        String url = extractUrl(content);
        if (url != null) {
            if (content.contains("douyin.com")) {
                if (content.contains("live.douyin.com")) {
                    System.out.println("直播");
                    return null;
                } else {
                    String dyUrlOrId = processContent(content);
                    String videoId = isNumeric(dyUrlOrId) ? dyUrlOrId : extractVideoId(dyUrlOrId);
                    if (videoId!=null){
                        JSONArray dyData = serverGetDy(videoId);
                        if (dyData != null && dyData.size() > 0) {
                            JSONObject jsonData = dyData.getJSONObject(0);
                            return buildDouYinData(jsonData);
                        }
                    }
                }
            }
        }
        return null;
    }
    private static JSONObject buildDouYinData(JSONObject jsonData) {
        JSONObject douYData = new JSONObject();
        douYData.put("desc", jsonData.getString("desc"));
        JSONObject author = jsonData.getJSONObject("author");
        douYData.put("nickname", author.getString("nickname"));
        JSONObject videoJson = jsonData.getJSONObject("video");
        JSONObject coverJson = videoJson.getJSONObject("cover");
        String coverUrl = coverJson.getJSONArray("url_list").getString(0);
        douYData.put("coverUrl", coverUrl);
        if (jsonData.getJSONArray("images") != null) {
            JSONArray images = jsonData.getJSONArray("images");
            JSONArray imageArray = new JSONArray();
            for (int i = 0; i < images.size(); i++) {
                JSONObject image = images.getJSONObject(i);
                JSONArray urlList = image.getJSONArray("url_list");
                imageArray.add(urlList.get(0));
            }
            douYData.put("type", 2);
            douYData.put("data", imageArray);
        } else {
            JSONObject playAddr = videoJson.getJSONObject("play_addr");
            String uri = playAddr.getString("uri");
            String videoUrl = "https://www.iesdouyin.com/aweme/v1/play/?video_id=" + uri + "&ratio=1080p&line=0";
            douYData.put("type", 1);
            douYData.put("data", videoUrl);
        }
        return douYData;
    }
    public static String processContent(String content) {
        String douyinUrl = extractMatch(content, "v\\.douyin\\.com/[a-zA-Z0-9]+");
        if (douyinUrl != null) {
            return "https://" + douyinUrl;
        }
        String digit = extractMatch(content, "\\d{19}");
        return digit;
    }
    private static String extractMatch(String content, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        return matcher.find() ? matcher.group(0) : null;
    }
    public static boolean isNumeric(String str) {
        return str.matches("\\d+");
    }
    private static String extractUrl(String text) {
        // 匹配网址的正则表达式
        String regex = "https?://\\S+";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        // 查找匹配的链接
        if (matcher.find()) {
            return matcher.group();
        }
        return null;
    }
    public static String extractVideoId(String link) {
        String redirectLink = getRedirectUrl(link);
        Pattern patternVideo = Pattern.compile("/video/(\\d+)");
        Pattern patternNote = Pattern.compile("/note/(\\d+)");
        Matcher matcherVideo = patternVideo.matcher(redirectLink);
        Matcher matcherNote = patternNote.matcher(redirectLink);
        if (matcherVideo.find()) {
            return matcherVideo.group(1);
        } else if (matcherNote.find()) {
            return matcherNote.group(1);
        } else {
            return null;
        }
    }
    public static String getRedirectUrl(String url) {
        OkHttpClient client = new OkHttpClient();
        try {
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();
            Response response = client.newCall(request).execute();
            return response.request().url().toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static JSONArray serverGetDy(String itemIds){
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request Request = new Request.Builder()
                //不知道这个a_bogus是啥 可能是个算法 随便填写或空即可
                .url("https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?reflow_source=reflow_page&item_ids="+itemIds+"&a_bogus=sdfds")
                .addHeader("content-type", "application/x-www-form-urlencoded")
                .get()
                .build();
        try {
            Response response = client.newCall(Request).execute();
            JSONObject jsonObject= JSONObject.parseObject(response.body().string());
            if (jsonObject.getInteger("status_code").equals(0)){
                return jsonObject.getJSONArray("item_list");
            }
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
//package cc.mrbird.febs.mall.test;
//
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import okhttp3.OkHttpClient;
//import okhttp3.Request;
//import okhttp3.Response;
//
//import java.io.IOException;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
//public class DYDelMark {
//    public static void main(String[] args) {
//        String content = "https://v.douyin.com/iLwxgYHE/";
//        JSONObject douYData = extractDouYinData(content);
//        if (douYData != null) {
//            System.out.println(douYData);
//        } else {
//            System.out.println(1);
//        }
//    }
//    private static JSONObject extractDouYinData(String content) {
//        String url = extractUrl(content);
//
//        if (url != null) {
//            if (content.contains("douyin.com")) {
//                if (content.contains("live.douyin.com")) {
//                    System.out.println("直播");
//                    return null;
//                } else {
//                    String dyUrlOrId = processContent(content);
//                    String videoId = isNumeric(dyUrlOrId) ? dyUrlOrId : extractVideoId(dyUrlOrId);
//                    if (videoId!=null){
//                        JSONArray dyData = serverGetDy(videoId);
//
//                        if (dyData != null && dyData.size() > 0) {
//                            JSONObject jsonData = dyData.getJSONObject(0);
//                            return buildDouYinData(jsonData);
//                        }
//                    }
//                }
//            }
//        }
//        return null;
//    }
//    private static JSONObject buildDouYinData(JSONObject jsonData) {
//        JSONObject douYData = new JSONObject();
//        douYData.put("desc", jsonData.getString("desc"));
//
//        JSONObject author = jsonData.getJSONObject("author");
//        douYData.put("nickname", author.getString("nickname"));
//
//        JSONObject videoJson = jsonData.getJSONObject("video");
//        JSONObject coverJson = videoJson.getJSONObject("cover");
//        String coverUrl = coverJson.getJSONArray("url_list").getString(0);
//        douYData.put("coverUrl", coverUrl);
//
//        if (jsonData.getJSONArray("images") != null) {
//            JSONArray images = jsonData.getJSONArray("images");
//            JSONArray imageArray = new JSONArray();
//
//            for (int i = 0; i < images.size(); i++) {
//                JSONObject image = images.getJSONObject(i);
//                JSONArray urlList = image.getJSONArray("url_list");
//                imageArray.add(urlList.get(0));
//            }
//
//            douYData.put("type", 2);
//            douYData.put("data", imageArray);
//        } else {
//            JSONObject playAddr = videoJson.getJSONObject("play_addr");
//            String uri = playAddr.getString("uri");
//            String videoUrl = "https://www.iesdouyin.com/aweme/v1/play/?video_id=" + uri + "&ratio=1080p&line=0";
//            douYData.put("type", 1);
//            douYData.put("data", videoUrl);
//        }
//
//        return douYData;
//    }
//    public static String processContent(String content) {
//        String douyinUrl = extractMatch(content, "v\\.douyin\\.com/[a-zA-Z0-9]+");
//        if (douyinUrl != null) {
//            return "https://" + douyinUrl;
//        }
//        String digit = extractMatch(content, "\\d{19}");
//        return digit;
//    }
//    private static String extractMatch(String content, String regex) {
//        Pattern pattern = Pattern.compile(regex);
//        Matcher matcher = pattern.matcher(content);
//        return matcher.find() ? matcher.group(0) : null;
//    }
//    public static boolean isNumeric(String str) {
//        return str.matches("\\d+");
//    }
//    private static String extractUrl(String text) {
//        // 匹配网址的正则表达式
//        String regex = "https?://\\S+";
//        Pattern pattern = Pattern.compile(regex);
//        Matcher matcher = pattern.matcher(text);
//
//        // 查找匹配的链接
//        if (matcher.find()) {
//            return matcher.group();
//        }
//
//        return null;
//    }
//    public static String extractVideoId(String link) {
//        String redirectLink = getRedirectUrl(link);
//        Pattern patternVideo = Pattern.compile("/video/(\\d+)");
//        Pattern patternNote = Pattern.compile("/note/(\\d+)");
//
//        Matcher matcherVideo = patternVideo.matcher(redirectLink);
//        Matcher matcherNote = patternNote.matcher(redirectLink);
//
//        if (matcherVideo.find()) {
//            return matcherVideo.group(1);
//        } else if (matcherNote.find()) {
//            return matcherNote.group(1);
//        } else {
//            return null;
//        }
//    }
//    public static String getRedirectUrl(String url) {
//        OkHttpClient client = new OkHttpClient();
//        try {
//            Request request = new Request.Builder()
//                    .url(url)
//                    .get()
//                    .build();
//            Response response = client.newCall(request).execute();
//            return response.request().url().toString();
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return null;
//    }
//    private static JSONArray serverGetDy(String itemIds){
//        OkHttpClient client = new OkHttpClient().newBuilder().build();
//        Request Request = new Request.Builder()
//                //不知道这个a_bogus是啥 可能是个算法 随便填写或空即可
//                .url("https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?reflow_source=reflow_page&item_ids="+itemIds+"&a_bogus=sdfds")
//                .addHeader("content-type", "application/x-www-form-urlencoded")
//                .get()
//                .build();
//        try {
//            Response response = client.newCall(Request).execute();
//            JSONObject jsonObject= JSONObject.parseObject(response.body().string());
//            if (jsonObject.getInteger("status_code").equals(0)){
//                return jsonObject.getJSONArray("item_list");
//            }
//            return null;
//        } catch (IOException e) {
//            e.printStackTrace();
//            return null;
//        }
//    }
//}
src/main/java/cc/mrbird/febs/mall/test/FingerPrint.java
@@ -1,317 +1,317 @@
package cc.mrbird.febs.mall.test;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
/**
 * 图片是采用phash算法,一共分为四步吧.
 *
 * 1.将图片缩放到16*16大小,这是我们选择的合适的大小,假如宽高不一样,直接将其压到16*16,去掉细节,只保留宏观;
 *
 * 2.图片一共是16*16的,共256个像素,我们将图片进行灰度化,灰度化就是只有黑白灰三种,从白到黑,一共分了255层;
 *
 * 3.灰度化之后将图片进行DCT转换(离散余弦变化),因为为了识别有的图片旋转,这个DCT转换是将图片进行了一种压缩算法;
 *
 * 4.我们对这个算法进行了优化,因为之前是计算像素的均值,我们为了更准确,我们取RGB,rgb一共分为255个像素,我们将255个像素分为16段,如果像素大于0-16记为0,17到32记为1,直到255,这样就得到255位的二进制,这就是这张图片的指纹码.
 *
 * 得到唯一标识的指纹码之后怎么去计算像素度呢?
 *
 * 通过汉明距离比较两个二进制距离,如果距离小于<10的话,我们就判定两张图片相似.如果两个指纹码(二进制)一模一样,我们就判定两个是一张图片,或者类似;
 */
/**
 * 视频相似度算法:
 * 视频的话我们是通过ffmpeg(ff am pig),它是一个专门处理视频的框架,可以从视频中按针提取图片.然后就按照图片的相似度取对比了...
 */
/**
 * https://blog.csdn.net/weixin_34095889/article/details/91923072?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171652008316800182787012%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171652008316800182787012&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-91923072-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E6%8A%8A%E5%9B%BE%E7%89%87%E8%BD%AC%E6%8D%A2%E6%88%90%E9%BB%91%E7%99%BD%E7%81%B0%E5%83%8F%E7%B4%A0%E9%A3%8E%E6%A0%BC&spm=1018.2226.3001.4187
 * 均值哈希实现图像指纹比较
 */
public class FingerPrint {
    public static void main(String[] args) {
        FingerPrint fp1 = null;
        FingerPrint fp2 = null;
        try {
            fp1 = new FingerPrint(ImageIO.read(new File("D:\\image\\F1.png")));
            fp2 = new FingerPrint(ImageIO.read(new File("D:\\image\\Z1.jpg")));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(fp1.toString(false));
        System.out.println(fp2.toString(false));
        System.out.printf("sim=%f",fp1.compare(fp2));
    }
    /**
     * 图像指纹的尺寸,将图像resize到指定的尺寸,来计算哈希数组
     */
    private static final int HASH_SIZE=16;
    /**
     * 保存图像指纹的二值化矩阵
     */
    private final byte[] binaryzationMatrix;
    public FingerPrint(byte[] hashValue) {
        if(hashValue.length!=HASH_SIZE*HASH_SIZE)
            throw new IllegalArgumentException(String.format("length of hashValue must be %d",HASH_SIZE*HASH_SIZE ));
        this.binaryzationMatrix=hashValue;
    }
    public FingerPrint(String hashValue) {
        this(toBytes(hashValue));
    }
    public FingerPrint (BufferedImage src){
        this(hashValue(src));
    }
    private static byte[] hashValue(BufferedImage src){
        BufferedImage hashImage = resize(src,HASH_SIZE,HASH_SIZE);
        byte[] matrixGray = (byte[]) toGray(hashImage).getData().getDataElements(0, 0, HASH_SIZE, HASH_SIZE, null);
        return  binaryzation(matrixGray);
    }
    /**
     * 从压缩格式指纹创建{@link FingerPrint}对象
     * @param compactValue
     * @return
     */
    public static FingerPrint createFromCompact(byte[] compactValue){
        return new FingerPrint(uncompact(compactValue));
    }
    public static boolean validHashValue(byte[] hashValue){
        if(hashValue.length!=HASH_SIZE)
            return false;
        for(byte b:hashValue){
            if(0!=b&&1!=b)return false;
        }
        return true;
    }
    public static boolean validHashValue(String hashValue){
        if(hashValue.length()!=HASH_SIZE)
            return false;
        for(int i=0;i<hashValue.length();++i){
            if('0'!=hashValue.charAt(i)&&'1'!=hashValue.charAt(i))return false;
        }
        return true;
    }
    public byte[] compact(){
        return compact(binaryzationMatrix);
    }
    /**
     * 指纹数据按位压缩
     * @param hashValue
     * @return
     */
    private static byte[] compact(byte[] hashValue){
        byte[] result=new byte[(hashValue.length+7)>>3];
        byte b=0;
        for(int i=0;i<hashValue.length;++i){
            if(0==(i&7)){
                b=0;
            }
            if(1==hashValue[i]){
                b|=1<<(i&7);
            }else if(hashValue[i]!=0)
                throw new IllegalArgumentException("invalid hashValue,every element must be 0 or 1");
            if(7==(i&7)||i==hashValue.length-1){
                result[i>>3]=b;
            }
        }
        return result;
    }
    /**
     * 压缩格式的指纹解压缩
     * @param compactValue
     * @return
     */
    private static byte[] uncompact(byte[] compactValue){
        byte[] result=new byte[compactValue.length<<3];
        for(int i=0;i<result.length;++i){
            if((compactValue[i>>3]&(1<<(i&7)))==0)
                result[i]=0;
            else
                result[i]=1;
        }
        return result;
    }
    /**
     * 字符串类型的指纹数据转为字节数组
     * @param hashValue
     * @return
     */
    private static byte[] toBytes(String hashValue){
        hashValue=hashValue.replaceAll("\\s", "");
        byte[] result=new byte[hashValue.length()];
        for(int i=0;i<result.length;++i){
            char c = hashValue.charAt(i);
            if('0'==c)
                result[i]=0;
            else if('1'==c)
                result[i]=1;
            else
                throw new IllegalArgumentException("invalid hashValue String");
        }
        return result;
    }
    /**
     * 缩放图像到指定尺寸
     * @param src
     * @param width
     * @param height
     * @return
     */
    private static BufferedImage resize(Image src,int width,int height){
        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_3BYTE_BGR);
        Graphics g = result.getGraphics();
        try{
            g.drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
        }finally{
            g.dispose();
        }
        return result;
    }
    /**
     * 计算均值
     * @param src
     * @return
     */
    private static  int mean(byte[] src){
        long sum=0;
        // 将数组元素转为无符号整数
        for(byte b:src)sum+=(long)b&0xff;
        return (int) (Math.round((float)sum/src.length));
    }
    /**
     * 二值化处理
     * @param src
     * @return
     */
    private static byte[] binaryzation(byte[]src){
        byte[] dst = src.clone();
        int mean=mean(src);
        for(int i=0;i<dst.length;++i){
            // 将数组元素转为无符号整数再比较
            dst[i]=(byte) (((int)dst[i]&0xff)>=mean?1:0);
        }
        return dst;
    }
    /**
     * 转灰度图像
     * @param src
     * @return
     */
    private static BufferedImage toGray(BufferedImage src){
        if(src.getType()==BufferedImage.TYPE_BYTE_GRAY){
            return src;
        }else{
            // 图像转灰
            BufferedImage grayImage = new BufferedImage(src.getWidth(), src.getHeight(),
                    BufferedImage.TYPE_BYTE_GRAY);
            new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(src, grayImage);
            return grayImage;
        }
    }
    @Override
    public String toString() {
        return toString(true);
    }
    /**
     * @param multiLine 是否分行
     * @return
     */
    public String toString(boolean multiLine) {
        StringBuffer buffer=new StringBuffer();
        int count=0;
        for(byte b:this.binaryzationMatrix){
            buffer.append(0==b?'0':'1');
            if(multiLine&&++count%HASH_SIZE==0)
                buffer.append('\n');
        }
        return buffer.toString();
    }
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof FingerPrint){
            return Arrays.equals(this.binaryzationMatrix,((FingerPrint)obj).binaryzationMatrix);
        }else
            return super.equals(obj);
    }
    /**
     * 与指定的压缩格式指纹比较相似度
     * @param compactValue
     * @return
     * @see #compare(FingerPrint)
     */
    public float compareCompact(byte[] compactValue){
        return compare(createFromCompact(compactValue));
    }
    /**
     * @param hashValue
     * @return
     * @see #compare(FingerPrint)
     */
    public float compare(String hashValue){
        return compare(new FingerPrint(hashValue));
    }
    /**
     * 与指定的指纹比较相似度
     * @param hashValue
     * @return
     * @see #compare(FingerPrint)
     */
    public float compare(byte[] hashValue){
        return compare(new FingerPrint(hashValue));
    }
    /**
     * 与指定图像比较相似度
     * @param image2
     * @return
     * @see #compare(FingerPrint)
     */
    public float compare(BufferedImage image2){
        return compare(new FingerPrint(image2));
    }
    /**
     * 比较指纹相似度
     * @param src
     * @return
     * @see #compare(byte[], byte[])
     */
    public float compare(FingerPrint src){
        if(src.binaryzationMatrix.length!=this.binaryzationMatrix.length)
            throw new IllegalArgumentException("length of hashValue is mismatch");
        return compare(binaryzationMatrix,src.binaryzationMatrix);
    }
    /**
     * 判断两个数组相似度,数组长度必须一致否则抛出异常
     * @param f1
     * @param f2
     * @return 返回相似度(0.0~1.0)
     */
    private static float compare(byte[] f1,byte[] f2){
        if(f1.length!=f2.length)
            throw new IllegalArgumentException("mismatch FingerPrint length");
        int sameCount=0;
        for(int i=0;i<f1.length;++i){
            if(f1[i]==f2[i])++sameCount;
        }
        return (float)sameCount/f1.length;
    }
    public static float compareCompact(byte[] f1,byte[] f2){
        return compare(uncompact(f1),uncompact(f2));
    }
    public static float compare(BufferedImage image1,BufferedImage image2){
        return new FingerPrint(image1).compare(new FingerPrint(image2));
    }
}
//package cc.mrbird.febs.mall.test;
//
//import javax.imageio.ImageIO;
//import java.awt.*;
//import java.awt.color.ColorSpace;
//import java.awt.image.BufferedImage;
//import java.awt.image.ColorConvertOp;
//import java.io.File;
//import java.io.IOException;
//import java.util.Arrays;
//
///**
// * 图片是采用phash算法,一共分为四步吧.
// *
// * 1.将图片缩放到16*16大小,这是我们选择的合适的大小,假如宽高不一样,直接将其压到16*16,去掉细节,只保留宏观;
// *
// * 2.图片一共是16*16的,共256个像素,我们将图片进行灰度化,灰度化就是只有黑白灰三种,从白到黑,一共分了255层;
// *
// * 3.灰度化之后将图片进行DCT转换(离散余弦变化),因为为了识别有的图片旋转,这个DCT转换是将图片进行了一种压缩算法;
// *
// * 4.我们对这个算法进行了优化,因为之前是计算像素的均值,我们为了更准确,我们取RGB,rgb一共分为255个像素,我们将255个像素分为16段,如果像素大于0-16记为0,17到32记为1,直到255,这样就得到255位的二进制,这就是这张图片的指纹码.
// *
// * 得到唯一标识的指纹码之后怎么去计算像素度呢?
// *
// * 通过汉明距离比较两个二进制距离,如果距离小于<10的话,我们就判定两张图片相似.如果两个指纹码(二进制)一模一样,我们就判定两个是一张图片,或者类似;
// */
///**
// * 视频相似度算法:
// * 视频的话我们是通过ffmpeg(ff am pig),它是一个专门处理视频的框架,可以从视频中按针提取图片.然后就按照图片的相似度取对比了...
// */
//
///**
// * https://blog.csdn.net/weixin_34095889/article/details/91923072?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171652008316800182787012%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171652008316800182787012&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-91923072-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E6%8A%8A%E5%9B%BE%E7%89%87%E8%BD%AC%E6%8D%A2%E6%88%90%E9%BB%91%E7%99%BD%E7%81%B0%E5%83%8F%E7%B4%A0%E9%A3%8E%E6%A0%BC&spm=1018.2226.3001.4187
// * 均值哈希实现图像指纹比较
// */
//public class FingerPrint {
//
//    public static void main(String[] args) {
//        FingerPrint fp1 = null;
//        FingerPrint fp2 = null;
//        try {
//            fp1 = new FingerPrint(ImageIO.read(new File("D:\\image\\F1.png")));
//            fp2 = new FingerPrint(ImageIO.read(new File("D:\\image\\Z1.jpg")));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        System.out.println(fp1.toString(false));
//        System.out.println(fp2.toString(false));
//        System.out.printf("sim=%f",fp1.compare(fp2));
//    }
//
//    /**
//     * 图像指纹的尺寸,将图像resize到指定的尺寸,来计算哈希数组
//     */
//    private static final int HASH_SIZE=16;
//    /**
//     * 保存图像指纹的二值化矩阵
//     */
//    private final byte[] binaryzationMatrix;
//    public FingerPrint(byte[] hashValue) {
//        if(hashValue.length!=HASH_SIZE*HASH_SIZE)
//            throw new IllegalArgumentException(String.format("length of hashValue must be %d",HASH_SIZE*HASH_SIZE ));
//        this.binaryzationMatrix=hashValue;
//    }
//    public FingerPrint(String hashValue) {
//        this(toBytes(hashValue));
//    }
//    public FingerPrint (BufferedImage src){
//        this(hashValue(src));
//    }
//    private static byte[] hashValue(BufferedImage src){
//        BufferedImage hashImage = resize(src,HASH_SIZE,HASH_SIZE);
//        byte[] matrixGray = (byte[]) toGray(hashImage).getData().getDataElements(0, 0, HASH_SIZE, HASH_SIZE, null);
//        return  binaryzation(matrixGray);
//    }
//    /**
//     * 从压缩格式指纹创建{@link FingerPrint}对象
//     * @param compactValue
//     * @return
//     */
//    public static FingerPrint createFromCompact(byte[] compactValue){
//        return new FingerPrint(uncompact(compactValue));
//    }
//
//    public static boolean validHashValue(byte[] hashValue){
//        if(hashValue.length!=HASH_SIZE)
//            return false;
//        for(byte b:hashValue){
//            if(0!=b&&1!=b)return false;
//        }
//        return true;
//    }
//    public static boolean validHashValue(String hashValue){
//        if(hashValue.length()!=HASH_SIZE)
//            return false;
//        for(int i=0;i<hashValue.length();++i){
//            if('0'!=hashValue.charAt(i)&&'1'!=hashValue.charAt(i))return false;
//        }
//        return true;
//    }
//    public byte[] compact(){
//        return compact(binaryzationMatrix);
//    }
//
//    /**
//     * 指纹数据按位压缩
//     * @param hashValue
//     * @return
//     */
//    private static byte[] compact(byte[] hashValue){
//        byte[] result=new byte[(hashValue.length+7)>>3];
//        byte b=0;
//        for(int i=0;i<hashValue.length;++i){
//            if(0==(i&7)){
//                b=0;
//            }
//            if(1==hashValue[i]){
//                b|=1<<(i&7);
//            }else if(hashValue[i]!=0)
//                throw new IllegalArgumentException("invalid hashValue,every element must be 0 or 1");
//            if(7==(i&7)||i==hashValue.length-1){
//                result[i>>3]=b;
//            }
//        }
//        return result;
//    }
//
//    /**
//     * 压缩格式的指纹解压缩
//     * @param compactValue
//     * @return
//     */
//    private static byte[] uncompact(byte[] compactValue){
//        byte[] result=new byte[compactValue.length<<3];
//        for(int i=0;i<result.length;++i){
//            if((compactValue[i>>3]&(1<<(i&7)))==0)
//                result[i]=0;
//            else
//                result[i]=1;
//        }
//        return result;
//    }
//    /**
//     * 字符串类型的指纹数据转为字节数组
//     * @param hashValue
//     * @return
//     */
//    private static byte[] toBytes(String hashValue){
//        hashValue=hashValue.replaceAll("\\s", "");
//        byte[] result=new byte[hashValue.length()];
//        for(int i=0;i<result.length;++i){
//            char c = hashValue.charAt(i);
//            if('0'==c)
//                result[i]=0;
//            else if('1'==c)
//                result[i]=1;
//            else
//                throw new IllegalArgumentException("invalid hashValue String");
//        }
//        return result;
//    }
//    /**
//     * 缩放图像到指定尺寸
//     * @param src
//     * @param width
//     * @param height
//     * @return
//     */
//    private static BufferedImage resize(Image src,int width,int height){
//        BufferedImage result = new BufferedImage(width, height,
//                BufferedImage.TYPE_3BYTE_BGR);
//        Graphics g = result.getGraphics();
//        try{
//            g.drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
//        }finally{
//            g.dispose();
//        }
//        return result;
//    }
//    /**
//     * 计算均值
//     * @param src
//     * @return
//     */
//    private static  int mean(byte[] src){
//        long sum=0;
//        // 将数组元素转为无符号整数
//        for(byte b:src)sum+=(long)b&0xff;
//        return (int) (Math.round((float)sum/src.length));
//    }
//    /**
//     * 二值化处理
//     * @param src
//     * @return
//     */
//    private static byte[] binaryzation(byte[]src){
//        byte[] dst = src.clone();
//        int mean=mean(src);
//        for(int i=0;i<dst.length;++i){
//            // 将数组元素转为无符号整数再比较
//            dst[i]=(byte) (((int)dst[i]&0xff)>=mean?1:0);
//        }
//        return dst;
//
//    }
//    /**
//     * 转灰度图像
//     * @param src
//     * @return
//     */
//    private static BufferedImage toGray(BufferedImage src){
//        if(src.getType()==BufferedImage.TYPE_BYTE_GRAY){
//            return src;
//        }else{
//            // 图像转灰
//            BufferedImage grayImage = new BufferedImage(src.getWidth(), src.getHeight(),
//                    BufferedImage.TYPE_BYTE_GRAY);
//            new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(src, grayImage);
//            return grayImage;
//        }
//    }
//
//    @Override
//    public String toString() {
//        return toString(true);
//    }
//    /**
//     * @param multiLine 是否分行
//     * @return
//     */
//    public String toString(boolean multiLine) {
//        StringBuffer buffer=new StringBuffer();
//        int count=0;
//        for(byte b:this.binaryzationMatrix){
//            buffer.append(0==b?'0':'1');
//            if(multiLine&&++count%HASH_SIZE==0)
//                buffer.append('\n');
//        }
//        return buffer.toString();
//    }
//    @Override
//    public boolean equals(Object obj) {
//        if(obj instanceof FingerPrint){
//            return Arrays.equals(this.binaryzationMatrix,((FingerPrint)obj).binaryzationMatrix);
//        }else
//            return super.equals(obj);
//    }
//
//    /**
//     * 与指定的压缩格式指纹比较相似度
//     * @param compactValue
//     * @return
//     * @see #compare(FingerPrint)
//     */
//    public float compareCompact(byte[] compactValue){
//        return compare(createFromCompact(compactValue));
//    }
//    /**
//     * @param hashValue
//     * @return
//     * @see #compare(FingerPrint)
//     */
//    public float compare(String hashValue){
//        return compare(new FingerPrint(hashValue));
//    }
//    /**
//     * 与指定的指纹比较相似度
//     * @param hashValue
//     * @return
//     * @see #compare(FingerPrint)
//     */
//    public float compare(byte[] hashValue){
//        return compare(new FingerPrint(hashValue));
//    }
//    /**
//     * 与指定图像比较相似度
//     * @param image2
//     * @return
//     * @see #compare(FingerPrint)
//     */
//    public float compare(BufferedImage image2){
//        return compare(new FingerPrint(image2));
//    }
//    /**
//     * 比较指纹相似度
//     * @param src
//     * @return
//     * @see #compare(byte[], byte[])
//     */
//    public float compare(FingerPrint src){
//        if(src.binaryzationMatrix.length!=this.binaryzationMatrix.length)
//            throw new IllegalArgumentException("length of hashValue is mismatch");
//        return compare(binaryzationMatrix,src.binaryzationMatrix);
//    }
//    /**
//     * 判断两个数组相似度,数组长度必须一致否则抛出异常
//     * @param f1
//     * @param f2
//     * @return 返回相似度(0.0~1.0)
//     */
//    private static float compare(byte[] f1,byte[] f2){
//        if(f1.length!=f2.length)
//            throw new IllegalArgumentException("mismatch FingerPrint length");
//        int sameCount=0;
//        for(int i=0;i<f1.length;++i){
//            if(f1[i]==f2[i])++sameCount;
//        }
//        return (float)sameCount/f1.length;
//    }
//    public static float compareCompact(byte[] f1,byte[] f2){
//        return compare(uncompact(f1),uncompact(f2));
//    }
//    public static float compare(BufferedImage image1,BufferedImage image2){
//        return new FingerPrint(image1).compare(new FingerPrint(image2));
//    }
//
//}
src/main/java/cc/mrbird/febs/mall/test/ImageToChar.java
@@ -1,156 +1,156 @@
package cc.mrbird.febs.mall.test;
import cn.hutool.core.util.ObjectUtil;
import com.madgag.gif.fmsware.AnimatedGifEncoder;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
 * 基于Java的图片字符画(含动图)
 * https://blog.csdn.net/weixin_53070478/article/details/127183821?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-4-127183821-blog-125549681.235^v43^pc_blog_bottom_relevance_base9&spm=1001.2101.3001.4242.3&utm_relevant_index=7
 */
public class ImageToChar {
    static char[] ss = " `.^,:~\"<!ct+{i7?u30pw4A8DX%#HWM".toCharArray();
    /**
     * 将输入的图片转换成灰度图片
     * @param bi
     * @return
     */
    public static BufferedWriter ImageToChar(BufferedImage bi,String target){        //定义灰度方法  返回值为BufferedImage对象
        int width = bi.getWidth();
        int height =bi.getHeight();
        BufferedWriter bw = null;  //构建新的对象模型
        try {
            bw = new BufferedWriter(new FileWriter(target),360);
            // 遍历图片的RGB值,把得到的灰度值存到bufferedImage_end中,然后返回bufferedImage_end
            int autoAdd = 2;//自增
            for (int j = 0; j < height; j += autoAdd) {
                for (int i = 0; i < width; i += autoAdd) {
                    int pixel = bi.getRGB(i, j);
                    int[] rgb = new int[3];
                    rgb[0] = pixel >> 16 & 0xff;
                    rgb[1] = pixel >> 8 & 0xff;
                    rgb[2] = pixel & 0xff;
                    int Gray = (rgb[0] * 28 + rgb[1] * 151 + rgb[2] * 77) >> 8; //通过三原色值计算像素点的灰度
                    int x = Gray * ss.length / 255 % ss.length;     //灰度值的百分比 计算出相应密度的字符表
                    bw.write(ss[x]);    //输出该字符
                    bw.write(ss[x]);
                }
                bw.newLine();
            }
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bw;
    }
    /**
     * GIF转图片
     * https://blog.csdn.net/adminstate/article/details/128917090?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171653969716800197097670%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171653969716800197097670&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-128917090-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E5%9B%BE%E7%89%87%E8%BD%ACGif&spm=1018.2226.3001.4187
     * @param args
     */
//    public static void main(String[] args) {
//        Integer scaleSize = 360;
//        GifDecoder gd = new GifDecoder();
//        try{
//            gd.read(Files.newInputStream(new File("D:\\image\\imageGif.gif").toPath()));
//            for (int i = 0; i < gd.getFrameCount(); i++) {  //逐帧转换为图片。
//                BufferedImage frame = gd.getFrame(i);
//                float width = frame.getWidth(); // 像素
//                float height = frame.getHeight(); // 像素
//                float scale = width/scaleSize;
//                BufferedImage buffImg = new BufferedImage(scaleSize, (int)(height/scale), BufferedImage.TYPE_INT_RGB);
//                //使用TYPE_INT_RGB修改的图片会变色
//                buffImg.getGraphics().drawImage(
//                        frame.getScaledInstance(scaleSize, (int)(height/scale), Image.SCALE_SMOOTH), 0,
//                        0, null);
//package cc.mrbird.febs.mall.test;
//
//                ImageIO.write(buffImg, "jpg", new File("D:\\image\\gif\\"+i+".png"));
//import cn.hutool.core.util.ObjectUtil;
//import com.madgag.gif.fmsware.AnimatedGifEncoder;
//
//import javax.imageio.ImageIO;
//import java.awt.image.BufferedImage;
//import java.io.BufferedWriter;
//import java.io.File;
//import java.io.FileWriter;
//import java.io.IOException;
//
///**
// * 基于Java的图片字符画(含动图)
// * https://blog.csdn.net/weixin_53070478/article/details/127183821?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-4-127183821-blog-125549681.235^v43^pc_blog_bottom_relevance_base9&spm=1001.2101.3001.4242.3&utm_relevant_index=7
// */
//public class ImageToChar {
//
//    static char[] ss = " `.^,:~\"<!ct+{i7?u30pw4A8DX%#HWM".toCharArray();
//
//    /**
//     * 将输入的图片转换成灰度图片
//     * @param bi
//     * @return
//     */
//    public static BufferedWriter ImageToChar(BufferedImage bi,String target){        //定义灰度方法  返回值为BufferedImage对象
//        int width = bi.getWidth();
//        int height =bi.getHeight();
//        BufferedWriter bw = null;  //构建新的对象模型
//        try {
//            bw = new BufferedWriter(new FileWriter(target),360);
//
//            // 遍历图片的RGB值,把得到的灰度值存到bufferedImage_end中,然后返回bufferedImage_end
//            int autoAdd = 2;//自增
//            for (int j = 0; j < height; j += autoAdd) {
//                for (int i = 0; i < width; i += autoAdd) {
//                    int pixel = bi.getRGB(i, j);
//                    int[] rgb = new int[3];
//                    rgb[0] = pixel >> 16 & 0xff;
//                    rgb[1] = pixel >> 8 & 0xff;
//                    rgb[2] = pixel & 0xff;
//                    int Gray = (rgb[0] * 28 + rgb[1] * 151 + rgb[2] * 77) >> 8; //通过三原色值计算像素点的灰度
//                    int x = Gray * ss.length / 255 % ss.length;     //灰度值的百分比 计算出相应密度的字符表
//                    bw.write(ss[x]);    //输出该字符
//                    bw.write(ss[x]);
//                }
//                bw.newLine();
//            }
//        }catch(IOException e){
//            System.out.println(e);
//            bw.flush();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return bw;
//    }
    /**
     * 图片转GIF
     * https://blog.csdn.net/adminstate/article/details/128917090?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171653969716800197097670%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171653969716800197097670&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-128917090-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E5%9B%BE%E7%89%87%E8%BD%ACGif&spm=1018.2226.3001.4187
     * @param args
     */
    public static void main(String[] args) {
        // 存放jpg文件目录
        String inpath = "D:\\image\\gif\\";
        //生成GIF
        AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder();
        animatedGifEncoder.setRepeat(0);
        animatedGifEncoder.start("D:\\image\\gif\\screenshot.gif");
        try{
            //获取目录下所有jpg及其他非gif图片文件
            String[] pic = new File(inpath).list();
            BufferedImage[] src = new BufferedImage[pic.length];
            for (int i = 0; i <= src.length; i++) {
                String pngPath = inpath + i + ".png";
                if(new File(pngPath).exists()){
                    animatedGifEncoder.setDelay(100); //设置播放间隔
                    src[i] = ImageIO.read(new File(pngPath)); // 读入需要播放的jpg文件
                    animatedGifEncoder.addFrame(src[i]);  //添加到帧中
                }
            }
            animatedGifEncoder.finish();
        }catch(IOException e){
            System.err.println("合成gif图失败");
        }
    }
    /**
     * 将GIF图片转换成字符串
     * @param args
     */
//    public static void main(String[] args) {
//        GifDecoder gd = new GifDecoder();
//        try{
//
//            gd.read(Files.newInputStream(new File("D:\\image\\gif\\screenshot.gif").toPath()));
//            System.out.println(gd.getFrameCount());
//            for (int i = 0; i < gd.getFrameCount(); i++) {  //逐帧转换为字符集。
//                System.out.println(gd.getFrameCount());
//                BufferedImage frame = gd.getFrame(i);
//                ImageToChar(frame,"D:\\image\\ImageToChar.txt");    //参数提供缓冲图片对象,以及目标文本输出地址。
//                try {
//                    Thread.sleep(500);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//    /**
//     * GIF转图片
//     * https://blog.csdn.net/adminstate/article/details/128917090?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171653969716800197097670%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171653969716800197097670&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-128917090-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E5%9B%BE%E7%89%87%E8%BD%ACGif&spm=1018.2226.3001.4187
//     * @param args
//     */
////    public static void main(String[] args) {
////        Integer scaleSize = 360;
////        GifDecoder gd = new GifDecoder();
////        try{
////            gd.read(Files.newInputStream(new File("D:\\image\\imageGif.gif").toPath()));
////            for (int i = 0; i < gd.getFrameCount(); i++) {  //逐帧转换为图片。
////                BufferedImage frame = gd.getFrame(i);
////                float width = frame.getWidth(); // 像素
////                float height = frame.getHeight(); // 像素
////                float scale = width/scaleSize;
////                BufferedImage buffImg = new BufferedImage(scaleSize, (int)(height/scale), BufferedImage.TYPE_INT_RGB);
////                //使用TYPE_INT_RGB修改的图片会变色
////                buffImg.getGraphics().drawImage(
////                        frame.getScaledInstance(scaleSize, (int)(height/scale), Image.SCALE_SMOOTH), 0,
////                        0, null);
////
////                ImageIO.write(buffImg, "jpg", new File("D:\\image\\gif\\"+i+".png"));
////            }
////        }catch(IOException e){
////            System.out.println(e);
////        }
////    }
//
//
//    /**
//     * 图片转GIF
//     * https://blog.csdn.net/adminstate/article/details/128917090?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171653969716800197097670%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171653969716800197097670&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-128917090-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E5%9B%BE%E7%89%87%E8%BD%ACGif&spm=1018.2226.3001.4187
//     * @param args
//     */
//    public static void main(String[] args) {
//        // 存放jpg文件目录
//        String inpath = "D:\\image\\gif\\";
//
//        //生成GIF
//        AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder();
//        animatedGifEncoder.setRepeat(0);
//        animatedGifEncoder.start("D:\\image\\gif\\screenshot.gif");
//
//        try{
//            //获取目录下所有jpg及其他非gif图片文件
//            String[] pic = new File(inpath).list();
//            BufferedImage[] src = new BufferedImage[pic.length];
//
//            for (int i = 0; i <= src.length; i++) {
//                String pngPath = inpath + i + ".png";
//                if(new File(pngPath).exists()){
//                    animatedGifEncoder.setDelay(100); //设置播放间隔
//                    src[i] = ImageIO.read(new File(pngPath)); // 读入需要播放的jpg文件
//                    animatedGifEncoder.addFrame(src[i]);  //添加到帧中
//                }
//            }
//            animatedGifEncoder.finish();
//        }catch(IOException e){
//            System.out.println(e);
//            System.err.println("合成gif图失败");
//        }
//    }
    /**
     * 将图片转换成字符串
     * @param args
     */
//    public static void main(String[] args) {
//        try{
//            ImageToChar(
//                    ImageIO.read(new File("D:\\image\\outDpi.png")),
//                    "D:\\image\\ImageToChar.txt");
//        }catch(IOException e){
//            System.out.println(e);
//        }
//    }
}
//
//    /**
//     * 将GIF图片转换成字符串
//     * @param args
//     */
////    public static void main(String[] args) {
////        GifDecoder gd = new GifDecoder();
////        try{
////
////            gd.read(Files.newInputStream(new File("D:\\image\\gif\\screenshot.gif").toPath()));
////            System.out.println(gd.getFrameCount());
////            for (int i = 0; i < gd.getFrameCount(); i++) {  //逐帧转换为字符集。
////                System.out.println(gd.getFrameCount());
////                BufferedImage frame = gd.getFrame(i);
////                ImageToChar(frame,"D:\\image\\ImageToChar.txt");    //参数提供缓冲图片对象,以及目标文本输出地址。
////                try {
////                    Thread.sleep(500);
////                } catch (InterruptedException e) {
////                    e.printStackTrace();
////                }
////            }
////        }catch(IOException e){
////            System.out.println(e);
////        }
////    }
//
//    /**
//     * 将图片转换成字符串
//     * @param args
//     */
////    public static void main(String[] args) {
////        try{
////            ImageToChar(
////                    ImageIO.read(new File("D:\\image\\outDpi.png")),
////                    "D:\\image\\ImageToChar.txt");
////        }catch(IOException e){
////            System.out.println(e);
////        }
////    }
//}
src/main/java/cc/mrbird/febs/mall/test/PixelateImage.java
@@ -1,95 +1,95 @@
package cc.mrbird.febs.mall.test;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class PixelateImage {
    public static void main(String[] args) {
        handleDpi(new File("D:\\image\\inputDpi.png"),50,50);
        getPixel("D:\\image\\input.png");
        try {
            resizeImage("D:\\image\\input.png","D:\\image\\output.png",360);//将图片压缩至100宽
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 功能:获取图片像素
     * * @param filePath 图片路径
     */
    public static void getPixel(String filePath){
        File file = new File(filePath);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int width = bi.getWidth(); // 像素
        int height = bi.getHeight(); // 像素
        System.out.println("width=" + width + ",height=" + height + ".");
    }
    /**
     * @param inputPath  源图片路径
     * @param outputPath  修改大小后图片路径
     * @param scaleSize 图片的修改比例,目标宽度
     */
    public static void resizeImage(String inputPath, String outputPath,int scaleSize) throws IOException {
        File srcFile = new File(inputPath);
        Image srcImg = ImageIO.read(srcFile);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(srcFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        float width = bi.getWidth(); // 像素
        float height = bi.getHeight(); // 像素
        float scale = width/scaleSize;
        BufferedImage buffImg = null;
        buffImg = new BufferedImage(scaleSize, (int)(height/scale), BufferedImage.TYPE_INT_RGB);
        //使用TYPE_INT_RGB修改的图片会变色
        buffImg.getGraphics().drawImage(
                srcImg.getScaledInstance(scaleSize, (int)(height/scale), Image.SCALE_SMOOTH), 0,
                0, null);
        ImageIO.write(buffImg, "JPEG", new File(outputPath));
    }
    /**
     * 改变图片DPI
     *
     * @param file
     * @param xDensity
     * @param yDensity
     */
    public static void handleDpi(File file, int xDensity, int yDensity) {
        try {
            BufferedImage image = ImageIO.read(file);
            JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(new FileOutputStream(file));
            JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);
            jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
            jpegEncoder.setJPEGEncodeParam(jpegEncodeParam);
            jpegEncodeParam.setQuality(0.1f, false);
            jpegEncodeParam.setXDensity(xDensity);
            jpegEncodeParam.setYDensity(yDensity);
            jpegEncoder.encode(image, jpegEncodeParam);
            image.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
//package cc.mrbird.febs.mall.test;
//
//import com.sun.image.codec.jpeg.JPEGCodec;
//import com.sun.image.codec.jpeg.JPEGEncodeParam;
//import com.sun.image.codec.jpeg.JPEGImageEncoder;
//
//import javax.imageio.ImageIO;
//import java.awt.*;
//import java.awt.image.BufferedImage;
//import java.io.File;
//import java.io.FileOutputStream;
//import java.io.IOException;
//
//public class PixelateImage {
//
//    public static void main(String[] args) {
//        handleDpi(new File("D:\\image\\inputDpi.png"),50,50);
//        getPixel("D:\\image\\input.png");
//        try {
//            resizeImage("D:\\image\\input.png","D:\\image\\output.png",360);//将图片压缩至100宽
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
//
//    /**
//     * 功能:获取图片像素
//     * * @param filePath 图片路径
//     */
//    public static void getPixel(String filePath){
//        File file = new File(filePath);
//        BufferedImage bi = null;
//        try {
//            bi = ImageIO.read(file);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        int width = bi.getWidth(); // 像素
//        int height = bi.getHeight(); // 像素
//        System.out.println("width=" + width + ",height=" + height + ".");
//    }
//
//
//    /**
//     * @param inputPath  源图片路径
//     * @param outputPath  修改大小后图片路径
//     * @param scaleSize 图片的修改比例,目标宽度
//     */
//    public static void resizeImage(String inputPath, String outputPath,int scaleSize) throws IOException {
//
//        File srcFile = new File(inputPath);
//        Image srcImg = ImageIO.read(srcFile);
//        BufferedImage bi = null;
//        try {
//            bi = ImageIO.read(srcFile);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        float width = bi.getWidth(); // 像素
//        float height = bi.getHeight(); // 像素
//        float scale = width/scaleSize;
//        BufferedImage buffImg = null;
//        buffImg = new BufferedImage(scaleSize, (int)(height/scale), BufferedImage.TYPE_INT_RGB);
//        //使用TYPE_INT_RGB修改的图片会变色
//        buffImg.getGraphics().drawImage(
//                srcImg.getScaledInstance(scaleSize, (int)(height/scale), Image.SCALE_SMOOTH), 0,
//                0, null);
//
//        ImageIO.write(buffImg, "JPEG", new File(outputPath));
//    }
//
//    /**
//     * 改变图片DPI
//     *
//     * @param file
//     * @param xDensity
//     * @param yDensity
//     */
//    public static void handleDpi(File file, int xDensity, int yDensity) {
//        try {
//            BufferedImage image = ImageIO.read(file);
//            JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(new FileOutputStream(file));
//            JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);
//            jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
//            jpegEncoder.setJPEGEncodeParam(jpegEncodeParam);
//            jpegEncodeParam.setQuality(0.1f, false);
//            jpegEncodeParam.setXDensity(xDensity);
//            jpegEncodeParam.setYDensity(yDensity);
//            jpegEncoder.encode(image, jpegEncodeParam);
//            image.flush();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
//}
src/main/java/cc/mrbird/febs/mall/test/getGray.java
@@ -1,51 +1,51 @@
package cc.mrbird.febs.mall.test;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
public class getGray {
    /**
     * 将输入的图片转换成灰度图片
     * @param bufferedImage_start
     * @return
     */
    public static BufferedImage gray(BufferedImage bufferedImage_start){        //定义灰度方法  返回值为BufferedImage对象
        int width = bufferedImage_start.getWidth();
        int height =bufferedImage_start.getHeight();
        BufferedImage bufferedImage_end = new BufferedImage(width,height, BufferedImage.TYPE_3BYTE_BGR );  //构建新的对象模型
        // 遍历图片的RGB值,把得到的灰度值存到bufferedImage_end中,然后返回bufferedImage_end
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pixel = bufferedImage_start.getRGB(x, y);
                int[] rgb = new int[3];    //分别表示红绿蓝RGB。
                rgb[0] = pixel >> 16 & 0xff;
                rgb[1] = pixel >> 8 & 0xff;
                rgb[2] = pixel & 0xff;
                int gray = (rgb[0] * 28 + rgb[1] * 151 + rgb[2] * 77) >> 8;
//                Color color = new Color(bufferedImage_start.getRGB(x,y));//构建Color获取图片像素点
//                int gray = (int)(color.getRed() * 0.2126 + color.getGreen() * 0.7152 + color.getBlue() * 0.0722);
                Color color_end = new Color(gray,gray,gray);   //将设置的像素设置到bufferedImage_end
                bufferedImage_end.setRGB(x,y,color_end.getRGB());
            }
        }
        return bufferedImage_end;
    }
    public static void main(String[] args) {
        try{
            RenderedImage rendImage =gray(ImageIO.read(new File("D:\\image\\inputDpi.png")));
            File file = new File("D:\\image\\outDpi.png");
            ImageIO.write(rendImage, "png", file);
        }catch(IOException e){
            System.out.println(e);
        }
    }
}
//package cc.mrbird.febs.mall.test;
//
//import javax.imageio.ImageIO;
//import java.awt.*;
//import java.awt.image.BufferedImage;
//import java.awt.image.RenderedImage;
//import java.io.File;
//import java.io.IOException;
//
//public class getGray {
//
//    /**
//     * 将输入的图片转换成灰度图片
//     * @param bufferedImage_start
//     * @return
//     */
//    public static BufferedImage gray(BufferedImage bufferedImage_start){        //定义灰度方法  返回值为BufferedImage对象
//        int width = bufferedImage_start.getWidth();
//        int height =bufferedImage_start.getHeight();
//        BufferedImage bufferedImage_end = new BufferedImage(width,height, BufferedImage.TYPE_3BYTE_BGR );  //构建新的对象模型
//        // 遍历图片的RGB值,把得到的灰度值存到bufferedImage_end中,然后返回bufferedImage_end
//        for (int y = 0; y < height; y++) {
//            for (int x = 0; x < width; x++) {
//
//                int pixel = bufferedImage_start.getRGB(x, y);
//                int[] rgb = new int[3];    //分别表示红绿蓝RGB。
//                rgb[0] = pixel >> 16 & 0xff;
//                rgb[1] = pixel >> 8 & 0xff;
//                rgb[2] = pixel & 0xff;
//                int gray = (rgb[0] * 28 + rgb[1] * 151 + rgb[2] * 77) >> 8;
//
////                Color color = new Color(bufferedImage_start.getRGB(x,y));//构建Color获取图片像素点
////                int gray = (int)(color.getRed() * 0.2126 + color.getGreen() * 0.7152 + color.getBlue() * 0.0722);
//                Color color_end = new Color(gray,gray,gray);   //将设置的像素设置到bufferedImage_end
//                bufferedImage_end.setRGB(x,y,color_end.getRGB());
//            }
//        }
//        return bufferedImage_end;
//    }
//
//    public static void main(String[] args) {
//        try{
//            RenderedImage rendImage =gray(ImageIO.read(new File("D:\\image\\inputDpi.png")));
//            File file = new File("D:\\image\\outDpi.png");
//            ImageIO.write(rendImage, "png", file);
//        }catch(IOException e){
//            System.out.println(e);
//        }
//    }
//
//}
src/main/java/cc/mrbird/febs/mall/test/imageTest.java
@@ -1,100 +1,100 @@
package cc.mrbird.febs.mall.test;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class imageTest {
    public static void main(String[] args) throws IOException {
//        File originalImage = new File("D:\\image\\out.png");
//        try{
//            RenderedImage rendImage =getGray.gray(ImageIO.read(new File("D:\\image\\input.png")));
//            ImageIO.write(rendImage, "png", originalImage);
//        }catch(IOException e){
//            System.out.println(e);
//        }
        File originalImage = new File("D:\\image\\input.png");
        System.out.println("源文件大小" + originalImage.length());
        File resizedImg1 = new File("D:\\image\\out3.png");
        resize(originalImage, resizedImg1, Integer.parseInt(Long.toString(originalImage.length())), 0.1f);
        System.out.println("0.1转换后文件大小" + resizedImg1.length());
    }
//        ## 遍历文件夹下图片批量压缩
//    public static void main(String[] args) throws IOException {
//        File folder = new File("C:\\Users\\Win\\Desktop\\faceImages");//文件夹路径
//        File[] listOfFiles = folder.listFiles();
//        for (int i = 0; i < listOfFiles.length; i++) {
//            if (listOfFiles[i].isFile()) {
//                File originalImage = listOfFiles[i];
//                System.out.println("源文件大小" + originalImage.length());
//                String fileName = originalImage.getName();
//                File resizedImg1 = new File("C:\\Users\\Win\\Desktop\\productImages\\" + fileName);
//                resize(originalImage, resizedImg1, 64, 0.9f);
//                System.out.println(fileName + "0.8转换后文件大小" + resizedImg1.length());
//            } else if (listOfFiles[i].isDirectory()) {
//                System.out.println("Directory " + listOfFiles[i].getName());
//            }
//        }
//package cc.mrbird.febs.mall.test;
//
//import com.sun.image.codec.jpeg.JPEGCodec;
//import com.sun.image.codec.jpeg.JPEGEncodeParam;
//import com.sun.image.codec.jpeg.JPEGImageEncoder;
//
//import javax.imageio.ImageIO;
//import javax.swing.*;
//import java.awt.*;
//import java.awt.image.BufferedImage;
//import java.awt.image.ConvolveOp;
//import java.awt.image.Kernel;
//import java.awt.image.RenderedImage;
//import java.io.File;
//import java.io.FileOutputStream;
//import java.io.IOException;
//
//public class imageTest {
//
//    public static void main(String[] args) throws IOException {
//
////        File originalImage = new File("D:\\image\\out.png");
////        try{
////            RenderedImage rendImage =getGray.gray(ImageIO.read(new File("D:\\image\\input.png")));
////            ImageIO.write(rendImage, "png", originalImage);
////        }catch(IOException e){
////            System.out.println(e);
////        }
//
//
//
//        File originalImage = new File("D:\\image\\input.png");
//        System.out.println("源文件大小" + originalImage.length());
//        File resizedImg1 = new File("D:\\image\\out3.png");
//        resize(originalImage, resizedImg1, Integer.parseInt(Long.toString(originalImage.length())), 0.1f);
//        System.out.println("0.1转换后文件大小" + resizedImg1.length());
//
//    }
    /**
     * 缩放图片(压缩图片质量,改变图片尺寸)
     * 若原图宽度小于新宽度,则宽度不变!
     * @param newWidth 新的宽度
     * @param quality  图片质量参数 0.7f 相当于70%质量
     */
    public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {
        if (quality > 1) {
        }
        ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
        Image i = ii.getImage();
        Image resizedImage = null;
        int iWidth = i.getWidth(null);
        int iHeight = i.getHeight(null);
        if (iWidth < newWidth) {
            newWidth = iWidth;
        }
        if (iWidth > iHeight) {
            resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
        } else {
            resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
        }
        Image temp = new ImageIcon(resizedImage).getImage();
        BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);
        Graphics g = bufferedImage.createGraphics();
        g.setColor(Color.white);
        g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
        g.drawImage(temp, 0, 0, null);
        g.dispose();
        float softenFactor = 0.05f;
        float[] softenArray = {0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0};
        Kernel kernel = new Kernel(3, 3, softenArray);
        ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
        bufferedImage = cOp.filter(bufferedImage, null);
        FileOutputStream out = new FileOutputStream(resizedFile);
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
        param.setQuality(quality, true);
        encoder.setJPEGEncodeParam(param);
        encoder.encode(bufferedImage);
    }
}
////        ## 遍历文件夹下图片批量压缩
////    public static void main(String[] args) throws IOException {
////        File folder = new File("C:\\Users\\Win\\Desktop\\faceImages");//文件夹路径
////        File[] listOfFiles = folder.listFiles();
////        for (int i = 0; i < listOfFiles.length; i++) {
////            if (listOfFiles[i].isFile()) {
////                File originalImage = listOfFiles[i];
////                System.out.println("源文件大小" + originalImage.length());
////                String fileName = originalImage.getName();
////                File resizedImg1 = new File("C:\\Users\\Win\\Desktop\\productImages\\" + fileName);
////                resize(originalImage, resizedImg1, 64, 0.9f);
////                System.out.println(fileName + "0.8转换后文件大小" + resizedImg1.length());
////            } else if (listOfFiles[i].isDirectory()) {
////                System.out.println("Directory " + listOfFiles[i].getName());
////            }
////        }
////
////
////    }
//
//    /**
//     * 缩放图片(压缩图片质量,改变图片尺寸)
//     * 若原图宽度小于新宽度,则宽度不变!
//     * @param newWidth 新的宽度
//     * @param quality  图片质量参数 0.7f 相当于70%质量
//     */
//    public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {
//        if (quality > 1) {
//        }
//        ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
//        Image i = ii.getImage();
//        Image resizedImage = null;
//        int iWidth = i.getWidth(null);
//        int iHeight = i.getHeight(null);
//        if (iWidth < newWidth) {
//            newWidth = iWidth;
//        }
//        if (iWidth > iHeight) {
//            resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
//        } else {
//            resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
//        }
//        Image temp = new ImageIcon(resizedImage).getImage();
//        BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);
//        Graphics g = bufferedImage.createGraphics();
//        g.setColor(Color.white);
//        g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
//        g.drawImage(temp, 0, 0, null);
//        g.dispose();
//        float softenFactor = 0.05f;
//        float[] softenArray = {0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0};
//        Kernel kernel = new Kernel(3, 3, softenArray);
//        ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
//        bufferedImage = cOp.filter(bufferedImage, null);
//        FileOutputStream out = new FileOutputStream(resizedFile);
//        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
//        param.setQuality(quality, true);
//        encoder.setJPEGEncodeParam(param);
//        encoder.encode(bufferedImage);
//    }
//}