批量压缩word中的图片

批量压缩word中的图片

一、问题

实验报告中包含了大量的图片,不压缩的情况下占用了非常大的空间,本学期一共收了7次实验报告,总计约2.6GB,这对于我的硬盘来说是一个不小的负担,所以需要对文档中的所有图片进行一次压缩。

二、原理

在office2007以前,word文档基本可以认为是一个二进制文件(doc后缀),是没有办法采用正常的方式进行编辑的,所以如果当我们用ms office写的doc文件用wps或其他开源的office工具打开后,大概率是会出现排版的问题的,这是对协议实现不完善的后果。
在office2007时,微软提出了新的基于xml的文件格式(docx后缀),通过使用xml对文件内容进行管理,然后将所有的xml文件、图片文件、视频文件等内容打包压缩为zip格式,然后将后缀名改为docx,即完成了word文件的创建。可以看出docx的改动是比doc要简单的,我这里采用的原理就是这样。

三、开干

1. 更改文件名

不巧的是,实验报告很多同学的学号和姓名之间加了空格,这在后续进行命令处理文件时,出现了问题,所以,这里先把文件名改一遍,如果有空格,则删除空格。

import os
# 创建一个列表,存放文件名
files = []
# 获取当前工作目录
path = os.getcwd()

def main():
    # 获取当前文件中所有文件名,如果结尾是doc
    # 则添加到files列表中,待处理
    for file in os.listdir(path):
        if file.endswith("doc"):
            files.append(file)
    rename()

def rename():
    # 遍历列表,如果文件名中出现了空格
    # 则:
    # 重命名该文件
    # 删除列表中的带空格的文件名
    # 添加更改后不带空格的文件名
    for file in files:
        if " " in file:
            filepath = path+"\\"+file
            os.rename(filepath, filepath.replace(" ", ""))
            files.remove(file)
            files.append(file.replace(" ", ""))

2. 更改文件格式

不巧的是,这次实验报告所有同学都是采用doc格式创建的,这里强势吐槽一下各位同学的计算机知识,虽然是计算机相关专业的。所以我们需要将doc转成docx。
这里查一句,如果是手动打开该文件,然后另存为docx文件,那么文件中的图片也是可以被压缩的,如果用python另存为,则不会被压缩,看来还是有问题的。要不也不会有下边压缩文件的操作了。
这里我们使用了python win32com库,安装win32com库可以 pip install pywin32 。代码如下:

from win32com import client as wc #导入模块

def convertDoc2Docx():
    word = wc.Dispatch("Word.Application") # 打开word应用程序
    for file in files:
        print("convert:"+file)
        filepath = path+"\\"+file
        #打开word文件
        doc = word.Documents.Open(filepath) 
        # 说是将文件名转为docx,实际上保存时后缀直接改成了zip
        # 所以目标文件名称后缀改一下
        filename = filepath.replace("doc", "zip")
        #另存为后缀为".docx"的文件,其中参数12指docx文件
        doc.SaveAs(filename, 12)
        #关闭原来word文件
        doc.Close() 
    word.Quit()

3. 解压docx文件

经过上述第二步以后,所有的doc文件已经被转换成了docx,这里使用了python自带的zipfile模块进行解压缩

import zipfile

def unzipDocx():
    for file in files:
        print("unzip:"+file)
        # 拼凑文件夹路径
        dirpath = path+"\\"+file.split(".")[0]
        # 拼凑文件名,zip格式结尾
        zippath = path+"\\"+file.replace("doc", "zip")
        # 创建目录,每个文件都有自己专属的目录,用以存放解压后的所有文件
        os.mkdir(dirpath)
        # 创建zipfile对象
        zp = zipfile.ZipFile(zippath, "r")
        # 解压缩
        zp.extractall(path=dirpath)
        # 关闭
        zp.close()
        # 删除zip文件
        os.remove(zippath)  

4、更改图片大小

直接上代码

import cv2
import numpy as np
import shutil
import subprocess

def resizeImage():
    for file in files:
        print("resize:"+file)
        # 拼凑图片文件所在的目录:“解压后的文件路径\word\media”
        # 也就是说所有的图片文件都是在media文件夹中
        imagepath = "\\".join([path, file.split(".")[0],"word", "media"])
        # 创建两个列表,保存两种不同的文件类型名称
        jpegfiles = []
        pngfiles = []
        # 区分两种文件名
        for tempfile in os.listdir(imagepath):
            if tempfile.endswith("jpeg"):
                jpegfiles.append(tempfile)
            elif tempfile.endswith("png"):
                pngfiles.append(tempfile)
        # 压缩jpeg文件
        for jpegfile in jpegfiles:
            print("resize:"+jpegfile)
            # 拼凑完整的待处理文件路径
            filepath = imagepath + "\\" + jpegfile
            # 这里需要注意,opencv好像是无法识别中文路径
            # 所以这里使用numpy模块先读取文件内容
            # 然后转换成opencv能够识别的图像信息
            img = cv2.imdecode(np.fromfile(filepath, dtype=np.uint8), -1)
            # os.rename(filepath, filepath+".bak")
            # 同样由于中文路径问题,所以这里先将文件缩小后保存到“D:\\temp\\”这个目录中
            # 然后使用shutil剪切到原来的media路径中
            tempfile = "D:\\temp\\" + jpegfile
            cv2.imwrite(tempfile,img,[cv2.IMWRITE_JPEG_QUALITY,30])
            shutil.move(tempfile, filepath)
		
        # png文件使用的是另一种处理方式
        # 最开始找了个工具pngquant,想着总得用上呀
        # 其实png用opencv也是可以处理的
        for pngfile in pngfiles:
            print("resize:"+pngfile)
            filepath = imagepath + "\\" + pngfile
            # 先将需要转换的文件移动到“D:\\temp\\”
            # 如果直接在当前文件夹更改的话,文件名会被改掉,然后还得改回来
            tempfile = "D:\\temp\\" + pngfile
            shutil.move(filepath, tempfile)
            # 拼凑命令,使用subprocess进行运行,也就是执行cmd命令
            # 这里需要注意的是,先下载pngquant,然后,解压,然后添加环境变量
            cmd = "pngquant --quality=10-20 {} --output D:\\temp\\temp.png".format(tempfile)
            subprocess.run(cmd)
            # 将更改后的文件移动到原来的文件夹
            shutil.move("D:\\temp\\temp.png", filepath)
            os.remove(tempfile)

5、 重新压缩

文件处理完后,显然是要重新压缩成为docx文件的,这里需要注意的是,压缩时,我们压缩的时文件夹中的内容,不是文件夹,如图:
image.png

def zipDocx():
    for file in files:
        print("zip:"+file)
        zipfile = path+"\\"+file.replace("doc", "zip")
        dirpath = path+"\\"+file.split(".")[0]
        # 压缩使用的时7z命令,当然也是需要添加到环境变量的
        # 其实也可以用zipfile进行压缩,但是我不知道哪里错了,总之没弄出来
        # 其实解压也可以用7z
        cmd ="7z a {} {}\\*".format(zipfile, dirpath)
        subprocess.run(cmd)
		# 重命名zip文件为docx
        dstfile = zipfile.replace("zip", "docx")
        os.rename(zipfile, dstfile)

完成

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值