调整图像大小,然后将其存储在数据库烧瓶中

Posted

技术标签:

【中文标题】调整图像大小,然后将其存储在数据库烧瓶中【英文标题】:resize image size then store it in database flask 【发布时间】:2021-12-08 16:56:21 【问题描述】:

我正在使用这种方式来绘制图像并使用烧瓶将其存储在我的数据库中:

class Gallery(db.Model):
    __tablename__ = 'Gallery'
    id = db.Column(db.Integer,  primary_key=True)
    title = db.Column(db.String(128), nullable=False)
    name = db.Column(db.String(128), nullable=False)
    data = db.Column(db.LargeBinary, nullable=False) 
    rendered_data = db.Column(db.Text, nullable=False)


def render_picture(data):
    render_pic = base64.b64encode(data).decode('ascii') 
    return render_pic


@app.route('/gallery/create', methods=['POST'])
def create_gallery():
   title = request.form['title']
   file = request.files['file']
   data = file.read()
   render_file = render_picture(data)

   newFile = Gallery(name=file.filename, data=data, rendered_data=render_file, title=title)
   db.session.add(newFile)
   db.session.commit()
   db.session.close()

它工作正常,但我需要先减小图像大小,然后再将其存储到我的数据库中 我以多种方式尝试了 Pillow,但它不适用于我存储图像的方式

谁能帮我缩小图片尺寸?

【问题讨论】:

目前还不清楚,至少对我来说,1) file 中有什么,2) render_picture() 的代码在哪里,3) Gallery() 做了什么。请说清楚。谢谢。 我编辑了我的代码,文件是图像 目前还不清楚您的文件中到底有什么。请以十六进制显示文件的前 20-30 个字节 - 如果您无法以十六进制转储,您可以使用 hexed.it 【参考方案1】:

在我的示例中,上传的图像被缩放并作为二进制数据存储在数据库中。要显示它,可以创建数据的数据 url,也可以将图像的数据下载为文件。

from flask import Flask
from flask import redirect, render_template, request, url_for, send_file
from flask_sqlalchemy import SQLAlchemy
from PIL import Image
import base64
import io

app = Flask(__name__)
db = SQLAlchemy(app)

class Gallery(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    img_data = db.Column(db.LargeBinary(),
        nullable=True, unique=False, index=False)

    @property
    def b64encoded(self):
        return base64.b64encode(self.img_data).decode()

with app.app_context():
    db.create_all()

@app.route('/', methods=['GET'])
def index():
    galleries = Gallery.query.all()
    return render_template('index.html', **locals())

def image_resize(file, size=84):
    img = Image.open(file)
    img_size = img.size
    img_ratio = size/img_size[0]
    img.thumbnail((img_size[0]*img_ratio, img_size[1]*img_ratio), Image.ANTIALIAS)
    return image_to_bytes(img)

def image_to_bytes(image):
    stream = io.BytesIO()
    image.save(stream, format='PNG')
    return stream.getvalue()

@app.route('/create', methods=['POST'])
def create():
    if not 'img' in request.files:
        abort(400)

    file = request.files['img']

    gallery = Gallery()
    gallery.img_data = image_resize(file)
    db.session.add(gallery)
    db.session.commit()

    return redirect(url_for('index'))

@app.route('/<int:gallery_id>/image')
def download_image(gallery_id):
    gallery = Gallery.query.get_or_404(gallery_id)
    if not gallery.img_data:
        abort(404)

    return send_file(
        io.BytesIO(gallery.img_data),
        as_attachment=False,
        mimetype='image/png'
    )

【讨论】:

感谢它像这样工作,我不需要将它存储为二进制数据我可以使用我的函数(render_file = render_picture(img_data))它会是相同的,但调整大小,我可以以同样的方式展示它。再次感谢【参考方案2】:

我无法真正理解您的文件中的内容以及您如何执行它,但只要它有效,就可以了。关于调整图像大小的问题,您可以使用 PIL(Python 图像库)。我不熟悉 base64 和 io,我认为您根本不需要它们。我调整图像大小的方式是:

您可以创建一个函数来执行此操作:

def save_picture(form_picture):
    random_hex = secrets.token_hex(8)

我使用可以导入的 Python 机密

 import secrets

它可以用来为图像生成一个随机名称,所以我们没有很多同名的图像,我已经将它指定为 8 位,如上所示。 form_picture 是这里的一个参数:

_,f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(app.root_path, 'static/profile_pics', 
picture_fn)  
output_size = (125, 125)
i = Image.open(form_picture)

这将定义图片的路径,将"static/profile_pics"picture_fn 变量连接起来,该变量是定义图片实际名称的变量名称。 output_size 函数指定图片为 125 像素。

i.thumbnail(output_size)
i.save(picture_path)
return picture_fn

最后保存上图。

【讨论】:

以上是关于调整图像大小,然后将其存储在数据库烧瓶中的主要内容,如果未能解决你的问题,请参考以下文章

easelJS - 使用 Javascript 调整图像大小,然后将其与 SpriteSheet 一起使用

将图像传递给 celery 任务

Flutter - 调整网络图像大小

在 PowerShell 中调整字节数组图像的大小

在上载到google cloud storage django之前调整图像大小

检索、调整大小并将图像保存回 Access 数据库图像字段