直接上代码
# import cv2
import base64
import numpy as np
import aiofiles
'''
file <==> bytes <==> numpy <==> file
bytes <==> base64
'''
# sudo apt-get install libturbojpeg
# pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git
# pip install PyTurboJPEG -U
# pip install exifread -U
try:
# 1 / 0
from nvjpeg import NvJpeg
jpeg = NvJpeg()
print('Using nvJPEG for JPEG decoding')
except Exception as e:
from turbojpeg import TurboJPEG, TJPF_GRAY, TJSAMP_GRAY, TJFLAG_PROGRESSIVE, TJFLAG_FASTUPSAMPLE, TJFLAG_FASTDCT
# import exifread
print('Using TurboJPEG for JPEG decoding')
jpeg = TurboJPEG()
# bytes 转 numpy
def bytes_to_numpy(image_bytes):
# image_np = np.frombuffer(image_bytes, dtype=np.uint8)
# image_np2 = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
# return image_np2
# 使用turbojpeg或者pynvjpeg加速
img_np = jpeg.decode(image_bytes)
return img_np
# bytes 转 base64
def bytes_to_base64(image_bytes):
image_base64 = base64.b64encode(image_bytes).decode('utf8')
return image_base64
# bytes 保存 文件
def bytes_to_file(image_bytes, file_path):
with open(file_path, 'wb') as f:
f.write(image_bytes)
# numpy 转 bytes
def numpy_to_bytes(image_np):
# data = cv2.imencode('.jpg', image_np)[1]
# image_bytes = data.tobytes()
# return image_bytes
image_bytes = jpeg.encode(img)
return image_bytes
# numpy 转 base64
def numpy_to_base64(image_np):
image_bytes = numpy_to_bytes(image_np)
image_base4 = bytes_to_base64(image_bytes)
return image_base4
# numpy 保存 文件
def numpy_to_file(image_np, file_path):
# cv2.imwrite(file_path, image_np)
imwrite(image_np, file_path)
# 文件 转 numpy
def file_to_numpy(file_path):
# image_np = cv2.imread(file_path)
image_np = imread(file_path)
return image_np
# 文件 转 字节
def file_to_bytes(file_path):
with open(file_path, 'rb') as f:
image_bytes = f.read()
return image_bytes
# 文件 转 base64
def file_to_base64(file_path):
image_bytes = file_to_bytes(file_path)
image_base64 = bytes_to_base64(image_bytes)
return image_base64
# base64 转 bytes
def base64_to_bytes(image_base64):
image_bytes = base64.b64decode(image_base64)
return image_bytes
# base64 转 numpy
def base64_to_numpy(image_base64):
image_bytes = base64_to_bytes(image_base64)
image_np = bytes_to_numpy(image_bytes)
return image_np
# base64 保存 文件
def base64_to_file(image_base64, file_path):
image_bytes = base64_to_bytes(image_base64)
bytes_to_file(image_bytes, file_path)
# 异步函数
async def async_bytes_to_file(image_bytes, file_path):
async with open(file_path, 'wb') as f:
await f.write(image_bytes)
async def async_file_to_bytes(file_path):
async with aiofiles.open(file_path, "rb") as f:
image_bytes = await f.read()
return image_bytes
async def async_file_to_base64(file_path):
image_bytes = await async_file_to_bytes(file_path)
image_base64 = bytes_to_base64(image_bytes)
return image_base64
async def async_base64_to_file(image_base64, file_path):
image_bytes = base64_to_bytes(image_base64)
await async_bytes_to_file(image_bytes, file_path)
async def async_file_to_numpy(file_path):
img_np = await imread(file_path)
return img_np
async def async_numpy_to_file(img_np, file_path):
await async_imwrite(img_np, file_path)
async def async_imread(file_path):
img_bytes = await async_file_to_bytes(file_path)
img_np = bytes_to_numpy(img_bytes)
return img_np
async def async_imwrite(img_np, file_path):
img_bytes = numpy_to_bytes(img_np)
await async_bytes_to_file(img_bytes, file_path)
def imread(file_path):
img_bytes = file_to_bytes(file_path)
img_np = bytes_to_numpy(img_bytes)
return img_np
def imwrite(img_np, file_path):
img_bytes = numpy_to_bytes(img_np)
bytes_to_file(img_bytes)
# 图像转置
def transpose_image(image, orientation):
if orientation == None: return image
val = orientation.values[0]
if val == 1:
return image
elif val == 2:
return np.fliplr(image)
elif val == 3:
return np.rot90(image, 2)
elif val == 4:
return np.flipud(image)
elif val == 5:
return np.rot90(np.flipud(image), -1)
elif val == 6:
return np.rot90(image, -1)
elif val == 7:
return np.rot90(np.flipud(image))
elif val == 8:
return np.rot90(image)
if __name__ == '__main__':
from time import perf_counter
"""
cpu使用率 gpu使用率 时间
原始解码 100% 0 10s
pynvjpeg 100% 20% 3s
turbojpeg 100% 0 4.2s
原始编码 100% 0 15s
pynvjpeg 100% 58% 2.5s
turbojpeg 100% 0 6s
"""
# 解码图片为BGR格式
img_bytes = file_to_bytes('../utils/tmp.png')
# s = perf_counter()
# for _ in range(500):
# img1 = bytes_to_numpy(img_bytes)
# e = perf_counter()
# print(e - s)
# s = perf_counter()
# for _ in range(500):
# img2 = jpeg.decode(img_bytes)
# e = perf_counter()
# print(e - s)
# s = perf_counter()
# for _ in range(500):
# # decoding input.jpg to BGR array with fast upsample and fast DCT. (i.e. fastest speed but lower accuracy)
# img3 = jpeg.decode(img_bytes, flags=TJFLAG_FASTUPSAMPLE | TJFLAG_FASTDCT)
# e = perf_counter()
# print(e - s)
# print(img3.shape)
#
# s = perf_counter()
# for _ in range(500):
# # direct rescaling 1/2 while decoding input.jpg to BGR array
# # 解码后的图片宽高为原始的一半
# img4 = jpeg.decode(img_bytes, scaling_factor=(1, 2))
# e = perf_counter()
# print(e - s)
# print(img4.shape)
# print(jpeg.scaling_factors)
# # decoding JPEG image properties
# width, height, jpeg_subsample, jpeg_colorspace = jpeg.decode_header(img_bytes)
# print(width, height, jpeg_subsample, jpeg_colorspace)
#
# # decoding input.jpg to YUV420 array
# buffer_array, plane_sizes = jpeg.decode_to_yuv(img_bytes)
#
# # decoding input.jpg to YUV planes
# planes = jpeg.decode_to_yuv_planes(img_bytes)
# decoding input.jpg to grayscale array
jpeg.decode(img_bytes, pixel_format=TJPF_GRAY)
# 编码
img = file_to_numpy("../utils/tmp.png")
# s = perf_counter()
# for _ in range(1000):
# img_bytes = numpy_to_bytes(img)
# e = perf_counter()
# print(e - s)
# s = perf_counter()
# for _ in range(1000):
# img_bytes = jpeg.encode(img)
# e = perf_counter()
# print(e - s)
# encoding BGR array to output.jpg with TJSAMP_GRAY subsample.
# 生成灰度图
bytes_to_file(jpeg.encode(img, jpeg_subsample=TJSAMP_GRAY), "tmp3.jpg")
# encoding BGR array to output.jpg with quality level 50.
bytes_to_file(jpeg.encode(img, quality=50), "tmp4.jpg")
# encoding BGR array to output.jpg with quality level 100 and progressive entropy coding.
bytes_to_file(jpeg.encode(img, quality=100, flags=TJFLAG_PROGRESSIVE), "tmp5.jpg")
# 图像转置
# using PyTurboJPEG with ExifRead to transpose an image if the image has an EXIF Orientation tag.
# 其他
# 无损抠图
# lossless crop image
bytes_to_file(jpeg.crop(img_bytes, 8, 8, 320, 240), 'crop.jpg')
print()