From 236437c099ee0d06d5abb607df101d3da2959456 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Tue, 28 May 2024 14:17:56 +0800
Subject: [PATCH] 图片上传

---
 src/main/java/cc/mrbird/febs/mall/test/FingerPrint.java   |  317 +++++++++++++++++++++
 src/main/java/cc/mrbird/febs/mall/test/PixelateImage.java |   95 ++++++
 src/main/java/cc/mrbird/febs/mall/test/ImageToChar.java   |  156 ++++++++++
 src/main/java/cc/mrbird/febs/mall/test/getGray.java       |   51 +++
 pom.xml                                                   |    6 
 src/main/java/cc/mrbird/febs/mall/test/DYDelMark.java     |  162 ++++++++++
 src/main/java/cc/mrbird/febs/mall/test/imageTest.java     |  100 ++++++
 7 files changed, 887 insertions(+), 0 deletions(-)

diff --git a/pom.xml b/pom.xml
index e9a9486..8f21dc9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,12 @@
     <dependencies>
 
         <dependency>
+            <groupId>com.madgag</groupId>
+            <artifactId>animated-gif-lib</artifactId>
+            <version>1.4</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.web3j</groupId>
             <artifactId>core</artifactId>
             <version>4.5.5</version>
diff --git a/src/main/java/cc/mrbird/febs/mall/test/DYDelMark.java b/src/main/java/cc/mrbird/febs/mall/test/DYDelMark.java
new file mode 100644
index 0000000..945de93
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/test/DYDelMark.java
@@ -0,0 +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;
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/test/FingerPrint.java b/src/main/java/cc/mrbird/febs/mall/test/FingerPrint.java
new file mode 100644
index 0000000..788a348
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/test/FingerPrint.java
@@ -0,0 +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));
+    }
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/test/ImageToChar.java b/src/main/java/cc/mrbird/febs/mall/test/ImageToChar.java
new file mode 100644
index 0000000..ea4d0a2
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/test/ImageToChar.java
@@ -0,0 +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);
+//
+//                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.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();
+//                }
+//            }
+//        }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);
+//        }
+//    }
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/test/PixelateImage.java b/src/main/java/cc/mrbird/febs/mall/test/PixelateImage.java
new file mode 100644
index 0000000..a1d2709
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/test/PixelateImage.java
@@ -0,0 +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();
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/test/getGray.java b/src/main/java/cc/mrbird/febs/mall/test/getGray.java
new file mode 100644
index 0000000..6b9815b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/test/getGray.java
@@ -0,0 +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);
+        }
+    }
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/test/imageTest.java b/src/main/java/cc/mrbird/febs/mall/test/imageTest.java
new file mode 100644
index 0000000..6458e9c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/test/imageTest.java
@@ -0,0 +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());
+//            }
+//        }
+//
+//
+//    }
+
+    /**
+     * 缩放图片(压缩图片质量,改变图片尺寸)
+     * 若原图宽度小于新宽度,则宽度不变!
+     * @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);
+    }
+}

--
Gitblit v1.9.1