# PyTurboJPEG
A Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.
## Prerequisites
- [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo/releases)
- [numpy](https://github.com/numpy/numpy)
## Example
```python
import cv2
from turbojpeg import TurboJPEG, TJPF_GRAY, TJSAMP_GRAY, TJFLAG_PROGRESSIVE, TJFLAG_FASTUPSAMPLE, TJFLAG_FASTDCT
# specifying library path explicitly
# jpeg = TurboJPEG(r'D:\turbojpeg.dll')
# jpeg = TurboJPEG('/usr/lib64/libturbojpeg.so')
# jpeg = TurboJPEG('/usr/local/lib/libturbojpeg.dylib')
# using default library installation
jpeg = TurboJPEG()
# decoding input.jpg to BGR array
in_file = open('input.jpg', 'rb')
bgr_array = jpeg.decode(in_file.read())
in_file.close()
cv2.imshow('bgr_array', bgr_array)
cv2.waitKey(0)
# decoding input.jpg to BGR array with fast upsample and fast DCT. (i.e. fastest speed but lower accuracy)
in_file = open('input.jpg', 'rb')
bgr_array = jpeg.decode(in_file.read(), flags=TJFLAG_FASTUPSAMPLE|TJFLAG_FASTDCT)
in_file.close()
cv2.imshow('bgr_array', bgr_array)
cv2.waitKey(0)
# direct rescaling 1/2 while decoding input.jpg to BGR array
in_file = open('input.jpg', 'rb')
bgr_array_half = jpeg.decode(in_file.read(), scaling_factor=(1, 2))
in_file.close()
cv2.imshow('bgr_array_half', bgr_array_half)
cv2.waitKey(0)
# getting possible scaling factors for direct rescaling
scaling_factors = jpeg.scaling_factors
# decoding JPEG image properties
in_file = open('input.jpg', 'rb')
width, height, jpeg_subsample, jpeg_colorspace = jpeg.decode_header(in_file.read())
in_file.close()
# decoding input.jpg to YUV array
in_file = open('input.jpg', 'rb')
buffer_array, plane_sizes = jpeg.decode_to_yuv(in_file.read())
in_file.close()
# decoding input.jpg to YUV planes
in_file = open('input.jpg', 'rb')
planes = jpeg.decode_to_yuv_planes(in_file.read())
in_file.close()
# encoding BGR array to output.jpg with default settings.
out_file = open('output.jpg', 'wb')
out_file.write(jpeg.encode(bgr_array))
out_file.close()
# encoding BGR array to output.jpg with TJSAMP_GRAY subsample.
out_file = open('output_gray.jpg', 'wb')
out_file.write(jpeg.encode(bgr_array, jpeg_subsample=TJSAMP_GRAY))
out_file.close()
# encoding BGR array to output.jpg with quality level 50.
out_file = open('output_quality_50.jpg', 'wb')
out_file.write(jpeg.encode(bgr_array, quality=50))
out_file.close()
# encoding BGR array to output.jpg with quality level 100 and progressive entropy coding.
out_file = open('output_quality_100_progressive.jpg', 'wb')
out_file.write(jpeg.encode(bgr_array, quality=100, flags=TJFLAG_PROGRESSIVE))
out_file.close()
# decoding input.jpg to grayscale array
in_file = open('input.jpg', 'rb')
gray_array = jpeg.decode(in_file.read(), pixel_format=TJPF_GRAY)
in_file.close()
cv2.imshow('gray_array', gray_array)
cv2.waitKey(0)
# scale with quality but leaves out the color conversion step
in_file = open('input.jpg', 'rb')
out_file = open('scaled_output.jpg', 'wb')
out_file.write(jpeg.scale_with_quality(in_file.read(), scaling_factor=(1, 4), quality=70))
out_file.close()
in_file.close()
# lossless crop image
out_file = open('lossless_cropped_output.jpg', 'wb')
out_file.write(jpeg.crop(open('input.jpg', 'rb').read(), 8, 8, 320, 240))
out_file.close()
```
```python
# using PyTurboJPEG with ExifRead to transpose an image if the image has an EXIF Orientation tag.
#
# pip install PyTurboJPEG -U
# pip install exifread -U
import cv2
import numpy as np
import exifread
from turbojpeg import TurboJPEG
def transposeImage(image, orientation):
"""See Orientation in https://www.exif.org/Exif2-2.PDF for details."""
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)
# using default library installation
turbo_jpeg = TurboJPEG()
# open jpeg file
in_file = open('foobar.jpg', 'rb')
# parse orientation
orientation = exifread.process_file(in_file).get('Image Orientation', None)
# seek file position back to 0 before decoding JPEG image
in_file.seek(0)
# start to decode the JPEG file
image = turbo_jpeg.decode(in_file.read())
# transpose image based on EXIF Orientation tag
transposed_image = transposeImage(image, orientation)
# close the file since it's no longer needed.
in_file.close()
cv2.imshow('transposed_image', transposed_image)
cv2.waitKey(0)
```
## Installation
### macOS
- brew install jpeg-turbo
- pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git
### Windows
- Download [libjpeg-turbo official installer](https://sourceforge.net/projects/libjpeg-turbo/files)
- pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git
### Linux
- RHEL/CentOS/Fedora
- Download [libjpeg-turbo.repo](https://libjpeg-turbo.org/pmwiki/uploads/Downloads/libjpeg-turbo.repo) to /etc/yum.repos.d/
- sudo yum install libjpeg-turbo-official
- pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git
- Ubuntu
- sudo apt-get update
- sudo apt-get install libturbojpeg
- pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git
## Benchmark
### macOS
- macOS Sierra 10.12.6
- Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
- opencv-python 3.4.0.12 (pre-built)
- turbo-jpeg 1.5.3 (pre-built)
| Function | Wall-clock time |
| ----------------------|-----------------|
| cv2.imdecode() | 0.528 sec |
| TurboJPEG.decode() | 0.191 sec |
| cv2.imencode() | 0.875 sec |
| TurboJPEG.encode() | 0.176 sec |
### Windows
- Windows 7 Ultimate 64-bit
- Intel(R) Xeon(R) E3-1276 v3 CPU @ 3.60 GHz
- opencv-python 3.4.0.12 (pre-built)
- turbo-jpeg 1.5.3 (pre-built)
| Function | Wall-clock time |
| ----------------------|-----------------|
| cv2.imdecode() | 0.358 sec |
| TurboJPEG.decode() | 0.135 sec |
| cv2.imencode() | 0.581 sec |
| TurboJPEG.encode() | 0.140 sec |
Raw data
{
"_id": null,
"home_page": "https://github.com/lilohuang/PyTurboJPEG",
"name": "PyTurboJPEG",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Lilo Huang",
"author_email": "kuso.cc@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/5a/65/237968ce82e6980a41064e0c16bddb20cc0f6132b8ae1762a1ac75a1afac/PyTurboJPEG-1.7.7.tar.gz",
"platform": null,
"description": "# PyTurboJPEG\nA Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.\n\n## Prerequisites\n- [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo/releases)\n- [numpy](https://github.com/numpy/numpy)\n\n## Example\n\n```python\nimport cv2\nfrom turbojpeg import TurboJPEG, TJPF_GRAY, TJSAMP_GRAY, TJFLAG_PROGRESSIVE, TJFLAG_FASTUPSAMPLE, TJFLAG_FASTDCT\n\n# specifying library path explicitly\n# jpeg = TurboJPEG(r'D:\\turbojpeg.dll')\n# jpeg = TurboJPEG('/usr/lib64/libturbojpeg.so')\n# jpeg = TurboJPEG('/usr/local/lib/libturbojpeg.dylib')\n\n# using default library installation\njpeg = TurboJPEG()\n\n# decoding input.jpg to BGR array\nin_file = open('input.jpg', 'rb')\nbgr_array = jpeg.decode(in_file.read())\nin_file.close()\ncv2.imshow('bgr_array', bgr_array)\ncv2.waitKey(0)\n\n# decoding input.jpg to BGR array with fast upsample and fast DCT. (i.e. fastest speed but lower accuracy)\nin_file = open('input.jpg', 'rb')\nbgr_array = jpeg.decode(in_file.read(), flags=TJFLAG_FASTUPSAMPLE|TJFLAG_FASTDCT)\nin_file.close()\ncv2.imshow('bgr_array', bgr_array)\ncv2.waitKey(0)\n\n# direct rescaling 1/2 while decoding input.jpg to BGR array\nin_file = open('input.jpg', 'rb')\nbgr_array_half = jpeg.decode(in_file.read(), scaling_factor=(1, 2))\nin_file.close()\ncv2.imshow('bgr_array_half', bgr_array_half)\ncv2.waitKey(0)\n\n# getting possible scaling factors for direct rescaling\nscaling_factors = jpeg.scaling_factors\n\n# decoding JPEG image properties\nin_file = open('input.jpg', 'rb')\nwidth, height, jpeg_subsample, jpeg_colorspace = jpeg.decode_header(in_file.read())\nin_file.close()\n\n# decoding input.jpg to YUV array\nin_file = open('input.jpg', 'rb')\nbuffer_array, plane_sizes = jpeg.decode_to_yuv(in_file.read())\nin_file.close()\n\n# decoding input.jpg to YUV planes\nin_file = open('input.jpg', 'rb')\nplanes = jpeg.decode_to_yuv_planes(in_file.read())\nin_file.close()\n\n# encoding BGR array to output.jpg with default settings.\nout_file = open('output.jpg', 'wb')\nout_file.write(jpeg.encode(bgr_array))\nout_file.close()\n\n# encoding BGR array to output.jpg with TJSAMP_GRAY subsample.\nout_file = open('output_gray.jpg', 'wb')\nout_file.write(jpeg.encode(bgr_array, jpeg_subsample=TJSAMP_GRAY))\nout_file.close()\n\n# encoding BGR array to output.jpg with quality level 50. \nout_file = open('output_quality_50.jpg', 'wb')\nout_file.write(jpeg.encode(bgr_array, quality=50))\nout_file.close()\n\n# encoding BGR array to output.jpg with quality level 100 and progressive entropy coding.\nout_file = open('output_quality_100_progressive.jpg', 'wb')\nout_file.write(jpeg.encode(bgr_array, quality=100, flags=TJFLAG_PROGRESSIVE))\nout_file.close()\n\n# decoding input.jpg to grayscale array\nin_file = open('input.jpg', 'rb')\ngray_array = jpeg.decode(in_file.read(), pixel_format=TJPF_GRAY)\nin_file.close()\ncv2.imshow('gray_array', gray_array)\ncv2.waitKey(0)\n\n# scale with quality but leaves out the color conversion step\nin_file = open('input.jpg', 'rb')\nout_file = open('scaled_output.jpg', 'wb')\nout_file.write(jpeg.scale_with_quality(in_file.read(), scaling_factor=(1, 4), quality=70))\nout_file.close()\nin_file.close()\n\n# lossless crop image\nout_file = open('lossless_cropped_output.jpg', 'wb')\nout_file.write(jpeg.crop(open('input.jpg', 'rb').read(), 8, 8, 320, 240))\nout_file.close()\n```\n\n```python\n# using PyTurboJPEG with ExifRead to transpose an image if the image has an EXIF Orientation tag.\n#\n# pip install PyTurboJPEG -U\n# pip install exifread -U\n\nimport cv2\nimport numpy as np\nimport exifread\nfrom turbojpeg import TurboJPEG\n\ndef transposeImage(image, orientation):\n \"\"\"See Orientation in https://www.exif.org/Exif2-2.PDF for details.\"\"\"\n if orientation == None: return image\n val = orientation.values[0]\n if val == 1: return image\n elif val == 2: return np.fliplr(image)\n elif val == 3: return np.rot90(image, 2)\n elif val == 4: return np.flipud(image)\n elif val == 5: return np.rot90(np.flipud(image), -1)\n elif val == 6: return np.rot90(image, -1)\n elif val == 7: return np.rot90(np.flipud(image))\n elif val == 8: return np.rot90(image)\n\n# using default library installation\nturbo_jpeg = TurboJPEG()\n# open jpeg file\nin_file = open('foobar.jpg', 'rb')\n# parse orientation\norientation = exifread.process_file(in_file).get('Image Orientation', None)\n# seek file position back to 0 before decoding JPEG image\nin_file.seek(0)\n# start to decode the JPEG file\nimage = turbo_jpeg.decode(in_file.read())\n# transpose image based on EXIF Orientation tag\ntransposed_image = transposeImage(image, orientation)\n# close the file since it's no longer needed.\nin_file.close()\n\ncv2.imshow('transposed_image', transposed_image)\ncv2.waitKey(0)\n```\n\n## Installation\n\n### macOS\n- brew install jpeg-turbo\n- pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git\n\n### Windows \n- Download [libjpeg-turbo official installer](https://sourceforge.net/projects/libjpeg-turbo/files) \n- pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git\n\n### Linux\n- RHEL/CentOS/Fedora\n - Download [libjpeg-turbo.repo](https://libjpeg-turbo.org/pmwiki/uploads/Downloads/libjpeg-turbo.repo) to /etc/yum.repos.d/\n - sudo yum install libjpeg-turbo-official\n - pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git\n\n- Ubuntu\n - sudo apt-get update\n - sudo apt-get install libturbojpeg\n - pip install -U git+https://github.com/lilohuang/PyTurboJPEG.git\n\n## Benchmark \n\n### macOS\n- macOS Sierra 10.12.6\n- Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz\n- opencv-python 3.4.0.12 (pre-built)\n- turbo-jpeg 1.5.3 (pre-built)\n\n| Function | Wall-clock time |\n| ----------------------|-----------------|\n| cv2.imdecode() \u00a0 \u00a0 \u00a0 | 0.528 sec \u00a0 |\n| TurboJPEG.decode() | 0.191 sec |\n| cv2.imencode() \u00a0 \u00a0 \u00a0 | 0.875 sec \u00a0 |\n| TurboJPEG.encode() | 0.176 sec |\n\n### Windows \n- Windows 7 Ultimate 64-bit\n- Intel(R) Xeon(R) E3-1276 v3 CPU @ 3.60 GHz\n- opencv-python 3.4.0.12 (pre-built)\n- turbo-jpeg 1.5.3 (pre-built)\n\n| Function | Wall-clock time |\n| ----------------------|-----------------|\n| cv2.imdecode() \u00a0 \u00a0 \u00a0 | 0.358 sec \u00a0 |\n| TurboJPEG.decode() | 0.135 sec |\n| cv2.imencode() \u00a0 \u00a0 \u00a0 | 0.581 sec \u00a0 |\n| TurboJPEG.encode() | 0.140 sec |\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python wrapper of libjpeg-turbo for decoding and encoding JPEG image.",
"version": "1.7.7",
"project_urls": {
"Homepage": "https://github.com/lilohuang/PyTurboJPEG"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5a65237968ce82e6980a41064e0c16bddb20cc0f6132b8ae1762a1ac75a1afac",
"md5": "78ed4f3fdc078d571e0f658e0f21a556",
"sha256": "2f1929f6bb32faf3c6007fbfbae1932e125b690173be60bcae03f678ffa4963b"
},
"downloads": -1,
"filename": "PyTurboJPEG-1.7.7.tar.gz",
"has_sig": false,
"md5_digest": "78ed4f3fdc078d571e0f658e0f21a556",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12075,
"upload_time": "2024-09-17T15:03:24",
"upload_time_iso_8601": "2024-09-17T15:03:24.393948Z",
"url": "https://files.pythonhosted.org/packages/5a/65/237968ce82e6980a41064e0c16bddb20cc0f6132b8ae1762a1ac75a1afac/PyTurboJPEG-1.7.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-17 15:03:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "lilohuang",
"github_project": "PyTurboJPEG",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pyturbojpeg"
}