【Java】批量处理图片

对图片批量处理,首先要获取大量的图片,并将其存入到某一路径中。下面是通过phython获取大量图片的爬虫代码:

# -*- coding:utf8 -*-
import requests
import json
from urllib import parse
import os
import time


class BaiduImageSpider(object):
    def __init__(self):
        self.json_count = 0  # 请求到的json文件数量(一个json文件包含30个图像文件)
        self.url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=5179920884740494226&ipn=rj&ct' \
                   '=201326592&is=&fp=result&queryWord={' \
                   '}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&word={' \
                   '}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&nojc=&pn={' \
                   '}&rn=30&gsm=1e&1635054081427= '
        self.directory = r"./imgs{}"  # 存储目录  这里需要修改为自己希望保存的目录  {}不要丢
        self.header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30 '
        }

    # 创建存储文件夹
    def create_directory(self, name):
        self.directory = self.directory.format(name)
        # 如果目录不存在则创建
        if not os.path.exists(self.directory):
            os.makedirs(self.directory)
        self.directory += r'\{}'

    # 获取图像链接
    def get_image_link(self, url):
        list_image_link = []
        strhtml = requests.get(url, headers=self.header)  # Get方式获取网页数据
        jsonInfo = json.loads(strhtml.text)
        for index in range(30):
            list_image_link.append(jsonInfo['data'][index]['thumbURL'])
        return list_image_link

    # 下载图片
    def save_image(self, img_link, filename):
        res = requests.get(img_link, headers=self.header)
        if res.status_code == 404:
            print(f"图片{img_link}下载出错------->")
        with open(filename, "wb") as f:
            f.write(res.content)
            print("存储路径:" + filename)

    # 入口函数
    def run(self):
        searchName = input("查询内容:")
        searchName_parse = parse.quote(searchName)  # 编码

        self.create_directory(searchName)

        pic_number = 0  # 图像数量
        for index in range(self.json_count):
            pn = (index+1)*30
            request_url = self.url.format(searchName_parse, searchName_parse, str(pn))
            list_image_link = self.get_image_link(request_url)
            for link in list_image_link:
                pic_number += 1
                self.save_image(link, self.directory.format(str(pic_number)+'.jpg'))
                time.sleep(0.2)  # 休眠0.2秒,防止封ip
        print(searchName+"----图像下载完成--------->")


if __name__ == '__main__':
    spider = BaiduImageSpider()
    spider.json_count = 30   # 定义下载10组图像,也就是三百张
    spider.run()

获取完图片之后,我们要对图片经行处理,先将编写一个功能将图片每个像素点对应的像素值存入数组当中,就是把图片转化为二维数组。

public int[][] getImage(String path){
        File file=new File(path);
        try {
            BufferedImage image = ImageIO.read(file);
            w=image.getWidth();
            h=image.getHeight();
            int[][] img=new int[w][h];
            for (int i = 0; i < w; i++) {
                for (int j = 0; j < h; j++) {
                    img[i][j]=image.getRGB(i,j);
                }
            }
            return img;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

这样方便我们后续对图片的访问,接下来是对图片的处理,对图片进行缩小,方法有两种,第一种是取样法,第二种是均值法。

public String process(int[][] arr){//取样法
        int bit=32;
        w-=w%bit;
        h-=h%bit;
        int di=w/bit;
        int dj=h/bit;
        String image="";//记录图片的二值编码方便后续的图片相似度对比
        for (int i = 0; i < w; i+=di) {
            for (int j = 0; j < h; j+=dj) {
                int pixNum=arr[i][j];
                Color color=new Color(pixNum);
                int red=color.getRed(),blue=color.getBlue(),green=color.getGreen();
                int grey=(red+blue+green)/3;
                if(grey>128){
                    image +="0";
                }else{
                    image +="1";
                }
                g.setColor(color);
                g.fillRect(400+i-(i-i/di),300+j-(j-j/dj),1,1);
            }
            image +="\n";
        }
        return image;
    }
public void meanProcess(int[][] arr){//均值法
        int bit=256;
        w-=w%bit;
        h-=h%bit;
        int di=w/bit;
        int dj=h/bit;
        for (int i = 0; i < w; i+=di) {
            for (int j = 0; j < h; j+=dj) {
                int red=0,blue=0,green=0;
                for(int a=i;a<i+di;a++){
                    for (int b = j; b < j+dj; b++) {
                        Color c=new Color(arr[a][b]);
                        red+=c.getRed();
                        blue+=c.getBlue();
                        green+=c.getGreen();
                    }
                }
                red/=di*dj;
                blue/=di*dj;
                green/=di*dj;
                Color color=new Color(red,green,blue);
                g.setColor(color);
                g.fillRect(400+i-(i-i/di),300+j-(j-j/dj),1,1);
            }
        }
    }

我们要对图片处理,图片又位于文件夹中,通过访问文件夹来遍历图片,来对图片进行批量处理。

        ArrayList<String> imgNameList=new ArrayList<>();
        ArrayList<String> BinCodeList=new ArrayList<>();
        ImageProcess process=new ImageProcess();
        File file=new File("C:\\Users\\lenovo\\Desktop\\图片");
        File[] file1=file.listFiles();
        for (int i = 0; i < file1.length; i++) {
            File f1=file1[i];
            System.out.println(f1.getAbsolutePath());
            File[] imageFile=f1.listFiles();
            for (int j = 0; j < imageFile.length; j++) {
                File img=imageFile[j];
                System.out.println(img.getAbsolutePath());
                int[][] imgArr= process.getImage(img.getAbsolutePath());
                String image=process.process(imgArr);
                System.out.println(image);
                imgNameList.add(img.getName());
                BinCodeList.add(image);
            }
        }

首先创造一个对图片进行处理类的对象,其中的成员方法包含上面的图片处理和图片转化成二维数组,File类其实指的是文件和文件夹,通过图片所在的文件夹对应的路径来创建File对象file,但是file中的内容仍然是文件夹,还要继续打开文件夹,通过for循环来访问每一张图片,输出图片的路径和二值编码,并创建动态数组来存储每张图片的二值编码和图片名字。接下来就是对选中的图片和其他图片进行对比,找到最为相似的那张图片。

方法就是对比图片二值编码每一位数,不同的话相似度差值就加一,值越小图片就越相似。

int[][] imgFile2=process.getImage("C:\\Users\\lenovo\\Desktop\\图片\\imgs汽车\\14.jpg");
        String binFile2=process.process(imgFile2);
        ArrayList<Integer> countList=new ArrayList<Integer>();
        for (int i = 0; i < BinCodeList.size(); i++) {
            String bin=BinCodeList.get(i);
            int count=0;
            for (int j = 0; j < binFile2.length(); j++) {
                char a1=binFile2.charAt(j);
                char a2=bin.charAt(j);
                if(a1!=a2){
                    count++;
                }
            }
            countList.add(count);
        }

比如我想查找其他图片和汽车中的第14张图片对比后的相似度差值,先取出对应的二维数组,然后转为二值编码,遍历存储的每张图片,然后将相似度存入动态数组中。我们还可以通过下面的方式来获取相似差值最小的图片。

        int min=countList.get(0);
        int minIndex=0;
        for (int i = 0; i < BinCodeList.size(); i++) {
            if(min>countList.get(i)&&countList.get(i)!=0){
                min=countList.get(i);
                minIndex=i;
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值