mirror of
https://github.com/licsber/Colorful-Black.git
synced 2024-09-19 23:30:23 +08:00
第一次提交 Init commit
第一次提交 Init commit
This commit is contained in:
parent
df8d6e89aa
commit
a133137d7b
31
README.md
31
README.md
@ -1,2 +1,29 @@
|
|||||||
# -
|
# 五彩斑斓的黑
|
||||||
把pdf变成五彩斑斓的pdf!
|
|
||||||
|
## 项目简介
|
||||||
|
|
||||||
|
把pdf文件转化为五彩斑斓的pdf!
|
||||||
|
这样看黑白论文的时候就不无聊了(
|
||||||
|
|
||||||
|
## 环境依赖
|
||||||
|
|
||||||
|
```
|
||||||
|
conda install flask imagemagick wand ghostscript opencv -c conda-forge
|
||||||
|
yum install mesa-libGL.x86_64
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运行
|
||||||
|
|
||||||
|
```
|
||||||
|
python server.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## TODOS
|
||||||
|
|
||||||
|
异步返回处理结果
|
||||||
|
使用`OSS`减轻网络io负担
|
||||||
|
更多文件图片格式支持
|
||||||
|
|
||||||
|
## 备注
|
||||||
|
|
||||||
|
写着玩的项目,看心情维护
|
||||||
|
58
color.py
Normal file
58
color.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import os
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def memoize(func):
|
||||||
|
cache = dict()
|
||||||
|
|
||||||
|
def memoized_func(*args):
|
||||||
|
if args in cache:
|
||||||
|
return cache[args]
|
||||||
|
result = func(*args)
|
||||||
|
cache[args] = result
|
||||||
|
return result
|
||||||
|
|
||||||
|
return memoized_func
|
||||||
|
|
||||||
|
|
||||||
|
@memoize
|
||||||
|
def get_color_img(width, height):
|
||||||
|
w = np.logspace(0, 255, height, base=1.01, dtype=np.uint8)
|
||||||
|
w = np.reshape(w, (-1, 1))
|
||||||
|
h = np.linspace(0, 255, width, dtype=np.uint8)
|
||||||
|
h = np.reshape(h, (1, -1))
|
||||||
|
shu = w * h
|
||||||
|
shu = np.reshape(shu, (height, -1))
|
||||||
|
shu = cv2.cvtColor(shu, cv2.COLOR_GRAY2BGR)
|
||||||
|
shu = cv2.applyColorMap(shu, cv2.COLORMAP_HSV)
|
||||||
|
|
||||||
|
w = np.linspace(0, 255, height, dtype=np.uint8)
|
||||||
|
w = np.reshape(w, (-1, 1))
|
||||||
|
h = np.logspace(0, 255, width, base=1.01, dtype=np.uint8)
|
||||||
|
h = np.reshape(h, (1, -1))
|
||||||
|
heng = w * h
|
||||||
|
heng = np.reshape(heng, (height, -1))
|
||||||
|
heng = cv2.cvtColor(heng, cv2.COLOR_GRAY2BGR)
|
||||||
|
heng = cv2.applyColorMap(heng, cv2.COLORMAP_HSV)
|
||||||
|
|
||||||
|
img = heng + shu
|
||||||
|
|
||||||
|
img = cv2.medianBlur(img, 101)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def mix_img(file_dir, filename, count):
|
||||||
|
path = os.path.join(file_dir, filename)
|
||||||
|
for i in range(1, count):
|
||||||
|
img = cv2.imread(path + str(i) + '.jpg')
|
||||||
|
color = get_color_img(img.shape[1], img.shape[0])
|
||||||
|
mask = (img == (0, 0, 0))[:, :, 0]
|
||||||
|
img[mask] = color[mask]
|
||||||
|
mix = img
|
||||||
|
cv2.imwrite(path + str(i) + '.jpg', mix)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
img = get_color_img(100, 100)
|
||||||
|
cv2.imwrite('tmp/1.jpg', img)
|
36
entity.py
Normal file
36
entity.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import pdf
|
||||||
|
import color
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Pdf:
|
||||||
|
def __init__(self, file_dir, filename, output_path):
|
||||||
|
self.file_dir = file_dir
|
||||||
|
self.filename = filename
|
||||||
|
self.pdf = pdf.parse_pdf(filepath=os.path.join(file_dir, filename))
|
||||||
|
self.page_count = 0
|
||||||
|
self.output_path = output_path
|
||||||
|
|
||||||
|
def extract(self, tmp_dir='tmp/'):
|
||||||
|
return pdf.save_pdf_as_img(pdf=self.pdf, filename=tmp_dir + self.filename)
|
||||||
|
|
||||||
|
def convert(self):
|
||||||
|
if self.page_count == 0:
|
||||||
|
return
|
||||||
|
color.mix_img(file_dir='tmp/', filename=self.filename, count=self.page_count)
|
||||||
|
return
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
return pdf.save_img_as_pdf(file_dir='tmp/', filename=self.filename,
|
||||||
|
count=self.page_count, output_dir=self.output_path, output_filename=self.filename)
|
||||||
|
|
||||||
|
def get_output_filename(self):
|
||||||
|
self.page_count = self.extract()
|
||||||
|
self.convert()
|
||||||
|
self.save()
|
||||||
|
return self.filename
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test = Pdf('/Users/licsber/PycharmProjects/五彩斑斓的黑/pdf', '1580826601.pdf', 'output')
|
||||||
|
print(test.get_output_filename())
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
32
pdf.py
Normal file
32
pdf.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from wand.image import Image as wi
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def parse_pdf(filepath, resolution=300):
|
||||||
|
pdf = wi(filename=filepath, resolution=resolution)
|
||||||
|
pdf = pdf.convert("jpeg")
|
||||||
|
return pdf
|
||||||
|
|
||||||
|
|
||||||
|
def save_pdf_as_img(pdf, filename):
|
||||||
|
page_count = 1
|
||||||
|
for img in pdf.sequence:
|
||||||
|
page = wi(image=img)
|
||||||
|
page.save(filename=filename + str(page_count) + '.jpg')
|
||||||
|
page_count += 1
|
||||||
|
return page_count
|
||||||
|
|
||||||
|
|
||||||
|
def save_img_as_pdf(file_dir, filename, count, output_dir, output_filename):
|
||||||
|
path = os.path.join(file_dir, filename)
|
||||||
|
output_path = os.path.join(output_dir, output_filename)
|
||||||
|
with wi() as w:
|
||||||
|
for i in range(1, count):
|
||||||
|
with wi(filename=path + str(i) + '.jpg') as page:
|
||||||
|
w.sequence.append(page)
|
||||||
|
w.save(filename=output_path)
|
||||||
|
return output_path
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
path = 'pdf/1580826601.pdf'
|
68
server.py
Normal file
68
server.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
from flask import Flask, render_template, send_from_directory, request
|
||||||
|
|
||||||
|
import entity
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
UPLOAD_FOLDER = 'pdf'
|
||||||
|
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||||
|
basedir = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
ALLOWED_EXTENSIONS = {'pdf'}
|
||||||
|
|
||||||
|
UPLOAD_HTML = 'upload.html'
|
||||||
|
OUTPUT_PATH = 'output'
|
||||||
|
output_dir = os.path.join(basedir, OUTPUT_PATH)
|
||||||
|
if not os.path.exists(output_dir):
|
||||||
|
os.makedirs(output_dir)
|
||||||
|
|
||||||
|
if not os.path.exists('tmp'):
|
||||||
|
os.makedirs('tmp')
|
||||||
|
|
||||||
|
file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
|
||||||
|
if not os.path.exists(file_dir):
|
||||||
|
os.makedirs(file_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def allowed_file(filename):
|
||||||
|
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def upload_test():
|
||||||
|
message = ''
|
||||||
|
return render_template(UPLOAD_HTML, message=message)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/upload', methods=['POST'], strict_slashes=False)
|
||||||
|
def api_upload():
|
||||||
|
f = request.files['myfile']
|
||||||
|
if f:
|
||||||
|
old_name = f.filename
|
||||||
|
ext = old_name.rsplit('.', 1)[1]
|
||||||
|
unix_time = int(time.time())
|
||||||
|
new_filename = old_name + str(unix_time) + '.' + ext
|
||||||
|
print(new_filename)
|
||||||
|
path = os.path.join(file_dir, new_filename)
|
||||||
|
f.save(path)
|
||||||
|
else:
|
||||||
|
message = '你没上传文件哦'
|
||||||
|
return render_template(UPLOAD_HTML, message=message)
|
||||||
|
if f and allowed_file(f.filename):
|
||||||
|
pdf = entity.Pdf(file_dir, new_filename, OUTPUT_PATH)
|
||||||
|
return downloader(pdf.get_output_filename())
|
||||||
|
else:
|
||||||
|
message = '文件类型不支持哦 重新上传试试呢'
|
||||||
|
return render_template(UPLOAD_HTML, message=message)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/download/<path:filename>")
|
||||||
|
def downloader(filename):
|
||||||
|
dir_path = os.path.join(app.root_path, 'output')
|
||||||
|
return send_from_directory(dir_path, filename, as_attachment=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print('启动目录:' + basedir)
|
||||||
|
app.run(host='0.0.0.0', port=10088)
|
33
templates/upload.html
Normal file
33
templates/upload.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>五彩斑斓的黑 - Licsber</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
|
||||||
|
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
|
||||||
|
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<div class="jumbotron">
|
||||||
|
<h3 id="header">{{message}}</h3>
|
||||||
|
<h2>欢迎试用一键五彩斑斓的黑,支持上传pdf。</h2>
|
||||||
|
<h2>创意By Licsber、Mikewang000000。</h2>
|
||||||
|
<form id="form1" method="post" action="/api/upload" enctype="multipart/form-data">
|
||||||
|
<div>
|
||||||
|
<input id="File1" type="file" name="myfile" class="btn btn-default btn-lg">
|
||||||
|
<button type="submit" class="btn btn-info btn-lg">提交</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var heading = $("#header")[0];
|
||||||
|
setInterval(function () {
|
||||||
|
if (heading.style.display == "block") {
|
||||||
|
heading.style.display = "none";
|
||||||
|
} else if (heading.style.display == "none") {
|
||||||
|
heading.style.display = "block";
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
</script>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user