惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Security @ Cisco Blogs
小众软件
小众软件
D
Docker
博客园_首页
A
About on SuperTechFans
P
Privacy International News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
A
Arctic Wolf
Spread Privacy
Spread Privacy
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Latest news
Latest news
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
大猫的无限游戏
大猫的无限游戏
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
V2EX - 技术
V2EX - 技术
SecWiki News
SecWiki News
U
Unit 42
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
S
Security Affairs
Y
Y Combinator Blog
aimingoo的专栏
aimingoo的专栏
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
T
Tenable Blog
W
WeLiveSecurity
Cloudbric
Cloudbric
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
Netflix TechBlog - Medium
F
Full Disclosure
N
News and Events Feed by Topic
D
DataBreaches.Net
P
Proofpoint News Feed
B
Blog RSS Feed
B
Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN Mintty Tips and Configurations Generating Table of Contents for Markdown with Tagbar Convert Python Script to Exe on Windows with Pyinstaller Ubuntu on Windows Missing after Windows Update 使用代理加速 Mac 终端下载速度 My Experience with Several Zsh Plugin Managers 深圳租房小记 How to Install zplug inside Docker Container Why don't settings inside bashrc or bash_profile take effect? Setting Up Locale in Linux 谷歌 Adsense 申请及在 Hugo 中的配置 How to Write Algorithm Pseudo Code in LaTeX Nifty Nvim Techniques That Make My Life Easier -- Series 4 A Few Grammar Questions in Writing How to Read and Write Images with Unicode Paths in OpenCV Creating A Professional Table in LaTeX with booktabs How to Create Proper Folding for Vim/Nvim Configuration Linux Tips and Tricks -- s1 JPEG Image Orientation and Exif How Do I Show the Current File Path In Neovim? JPEG Image Quality in PIL Difference between view, reshape, transpose and permute in PyTorch Convert PIL or OpenCV Image to Bytes without Saving to Disk Fast Movement and Navigation Inside Vim or Neovim Unintuitive Behaviour of Case Sensitivity in Python glob Binding Keys in Zsh 几把机械键盘试用体验 Nvim Autocompletion with Deoplete Converting Markdown to Beautiful PDF with Pandoc Exclusive and Inclusive Motion in Neovim/Vim Nifty Nvim Techniques Which Make My Life Easier -- Series 3 Why Doesn't Jedi Autocompletion Work for Some Methods Vim-like Editing inside Browser Markdown 生成 HTML 时汉字之间出现多余空格问题 小米 9 安装谷歌商店(Google Play Store)与相关配置 Create Mappings That Take A Count in Neovim Spell Checking in Nvim English Words Completion inside Neovim/Vim How to Use Python Inside Vim Script with Neovim Nifty Little Nvim Techniques to Make My Life Easier -- Series 2 Setting up Ultisnips for Neovim Mac 上罗技 M590 鼠标设置 Nifty Little Nvim Techniques to Make My Life Easier -- Series 1 A Complete Guide on Writing LaTeX with Vimtex in Neovim Manipulating Images with Alpha Channels in Pillow Sublime Text Regular Expression Cheat Sheet Cropping Rotated Rectangles from Image with OpenCV Boosting Your Productivity on Terminal with Zsh and Plugins 最新版 Rime 输入法使用 (2022 更新) Display Image with Pillow inside Ubuntu on Windows Faster Directory Navigation with z.lua Cmder Advanced Configurations Nvim-qt Settings on Windows 10 Tmux Plugin Install and Management How to Debug Python Code in Terminal Markdown Writing and Previewing in Neovim -- A Complete Guide Line Number Settings for More Efficient Movement in Neovim 两个大规模中文语料库介绍以及处理 Windows 系统下几款程序员不可不用的神器 我的 2018 阅读清单 A Complete Guide to Neovim Configuration for Python Development How Is Newline Handled in Python and Various Editors? Two Issues Related to ImageFont Module in PIL 在 Listary 中调用 GoldenDict 或欧路词典查单词 Reading and Writing Text Files on Windows The Mathematics behind Font Shapes --- Bézier Curves and More 快速识别图片字体:字体识别工具介绍 Deoplete Failed to Load at Startup after Updating Python neovim Package What Is The Difference between pip, pip3 and pip3.6 Shipped with Anaconda3? Windows 10 系统下 Neovim 安装与配置
Build Web API with Flask -- Post and Receive Image
2020-04-12 · via jdhao's digital space

In this post, I want to write about how to build a simple image processing web API that returns the size of an image. The topics include how to build this web API with Flask and how to post image to this web API and get response.

There are mainly two ways by which we can send an image to the web service. Based on how you send the image, the way to get the uploaded image on the server side also varies.

Post binary image#

You can directly post binary image to the server using the files parameter of requests.post():

url = 'http://127.0.0.1:5000/im_size'
my_img = {'image': open('test.jpg', 'rb')}
r = requests.post(url, files=my_img)

# convert server response into JSON format.
print(r.json())

In the above code, the Content-Type of the Header of the POST request will be multipart/form-data. Then in the server side, you can get the posted image like this:

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/im_size", methods=["POST"])
def process_image():
    file = request.files['image']
    # Read the image via file.stream
    img = Image.open(file.stream)

    return jsonify({'msg': 'success', 'size': [img.width, img.height]})


if __name__ == "__main__":
    app.run(debug=True)

In the server side, the posted image will be in request.files['image'], which is of type werkzeug.datastructures.FileStorage. You can save the image to disk via save() method of this object:

file.save('im-received.jpg')

The image is also stored in file.stream, which is a file-like object so that you can easily read the image for later processing:

# img is PIL Image object
img = Image.open(file.stream)

Finally, we construct a Python dict and convert it to JSON format via the jsonify() method provided by Flask.

How to post multiple files#

To post multiple images to the server, you can post a list of file tuples like the following:

multiple_files = [
    ('image', ('test.jpg', open('test.jpg', 'rb'))),
    ('image', ('test.jpg', open('test.jpg', 'rb')))
]
# simplified form
# multiple_files = [
#     ('image', open('test.jpg', 'rb')),
#     ('image', open('test.jpg', 'rb'))
# ]
r = requests.post(url, files=multiple_files, data=data)

In the server side, you can still receive the posted images using request.files:

from flask import Flask, request
# ... other code
files = request.files.to_dict(flat=False) ## files is a list containing two images.
for i, file in enumerate(files):
    file.save(f'image-{i}.jpg')

Post additional data#

We usually want to post more meta info than merely the image itself. We can use the data parameter in requests.post():

payload = {'id': '123', 'type': 'jpg'}
r = requests.post(url, files=files, data=payload)

To get the payload dict in the server side, we use request.form, which is of type werkzeug.datastructures.ImmutableMultiDict. We use request.form.to_dict() to convert the received form data into Python dict:

payload = request.form.to_dict()
id = payload['id']
im_type = payload['type']

Post base64 encoded image#

Another way is to just encode the image with base64 and post all the info via data parameter in requests.post() in the client side.

import base64

with open('test.jpg', 'rb') as f:
    im_b64 = base64.b64encode(f.read())

payload = {'id': '123', 'type': 'jpg', 'box': [0, 0, 100, 100], 'image': im_b64}

In the server side, we fetch the posted payload, get the base64 encoded image and decode it:

import base64
import io
from PIL import Image

payload = request.form.to_dict(flat=False)

im_b64 = payload['image'][0]  # remember that now each key corresponds to list.
# see https://jdhao.github.io/2020/03/17/base64_opencv_pil_image_conversion/
# for more info on how to convert base64 image to PIL Image object.
im_binary = base64.b64decode(im_b64)
buf = io.BytesIO(im_binary)
img = Image.open(buf)

Post multiple based64 encoded image#

To post multiple base64 encoded images to the server, post them as a list of base64 string:

b64_ims = []
for im_path in im_paths:
    with open(im_path, 'rb') as f:
        im_b64 = base64.encode(f.read())
    b64_ims.append(im_b64)
payload = {"images": b64_ims}

In the server side, you can get the posted dict and decode the base64 image one by one, just like what I have shown above for a single image.

References#