欢迎关注我们~
今天突然需要压缩pdf,网上都要收钱贼坑,于是乎决定一切的一切都要靠自己,给自己省几块钱的压缩费吧: )
基本思路就是,把pdf拆成jpg图片然后用SVD压缩图片,再拼接成PDF。
这次用的pdf是这个
import globimport fitzimport os pdffile = "123.pdf"doc = fitz.open(pdffile)width, height = fitz.PaperSize("a4") totaling = doc.pageCountfor pg in range(totaling): page = doc[pg] zoom = int(150) rotate = int(0) print(page) trans = fitz.Matrix(zoom / 100.0, zoom / 100.0).preRotate(rotate) pm = page.getPixmap(matrix=trans, alpha=False) lurl='pdf{}.jpg'.format(str((pg+1)/10)) pm.writePNG(lurl)doc.close()
这一步就把pdf拆成图片了
然后用SVD批量压缩图片(这里有点慢···)
from PIL import Image import numpy as np def rebuild_img(u, sigma, v, p):#p表示奇异值的百分比 m = len(u) n = len(v) a = np.zeros((m, n)) count = (int)(sum(sigma)) curSum = 0 k = 0 while curSum <= count * p: uk = u[:, k].reshape(m, 1) vk = v[k].reshape(1, n) a += sigma[k] * np.dot(uk, vk) curSum += sigma[k] k += 1 a[a < 0] = 0 a[a > 255] = 255 return np.rint(a).astype("uint8") PATH = []for i in range(58): PATH.append(Image.open("pdf"+str((i+1)/10)+".jpg"))for i in range(len(PATH)): a = np.array(PATH[i]) p=1 u, sigma, v = np.linalg.svd(a[:, :, 0]) R = rebuild_img(u, sigma, v, p) u, sigma, v = np.linalg.svd(a[:, :, 1]) G = rebuild_img(u, sigma, v, p) u, sigma, v = np.linalg.svd(a[:, :, 2]) B = rebuild_img(u, sigma, v, p) I = np.stack((R, G, B), 2) # 建个新的文件夹,路径要改 path = 'C:/Users/yzzpp/Desktop/python 1/练手/lian/out/' Image.fromarray(I).save(path+"pdf"+str((i+1)/10) + ".jpg
然后是这样的:
这些是压缩过的图片
然后把这些图片集合成pdf:
import globimport fitzimport osdef pictopdf(): doc = fitz.open() for img in glob.glob('*.jpg'): print(img) imgdoc = fitz.open(img) pdfbytes = imgdoc.convertToPDF() imgpdf = fitz.open("pdf", pdfbytes) doc.insertPDF(imgpdf) if os.path.exists("newpdf.pdf"): os.remove("newpdf.pdf") doc.save("newpdf.pdf") doc.close()pictopdf()
对比下压缩前后的图片大小和效果:
压缩前:
压缩后:
最后总大小对比:
因为本身这份123.pdf就在网上压缩过,所以效果就没那么明显了。
OK 给自己省了几块钱,舒服。
END
Miya
小小分享,期待更多
欢迎诸位讨论&指正