{"id":15008848,"url":"https://github.com/lilohuang/pyturbojpeg","last_synced_at":"2026-02-21T04:09:33.159Z","repository":{"id":28176291,"uuid":"117120390","full_name":"lilohuang/PyTurboJPEG","owner":"lilohuang","description":"PyTurboJPEG is a highly optimized Python wrapper of libjpeg-turbo (TurboJPEG API) which supports x86 and ARM architecture.","archived":false,"fork":false,"pushed_at":"2025-02-11T14:09:22.000Z","size":122,"stargazers_count":271,"open_issues_count":1,"forks_count":43,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-06T21:09:24.376Z","etag":null,"topics":["arm","decoding","embedded-systems","image-processing","jpeg-turbo","libjpeg","libjpeg-turbo","macos","opencv-python","pypy","python","python-wrapper","python2","python3","real-time","simd-optimizations","simd-parallelism","turbo-jpeg","turbojpeg","x86"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lilohuang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-11T15:57:52.000Z","updated_at":"2025-03-27T19:47:15.000Z","dependencies_parsed_at":"2023-12-12T11:04:46.215Z","dependency_job_id":"49c668f9-78c5-488d-8d60-49160334349e","html_url":"https://github.com/lilohuang/PyTurboJPEG","commit_stats":{"total_commits":67,"total_committers":10,"mean_commits":6.7,"dds":"0.17910447761194026","last_synced_commit":"c9a4973ab48e1e3d421881f76d8b1b2a22669fd2"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lilohuang%2FPyTurboJPEG","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lilohuang%2FPyTurboJPEG/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lilohuang%2FPyTurboJPEG/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lilohuang%2FPyTurboJPEG/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lilohuang","download_url":"https://codeload.github.com/lilohuang/PyTurboJPEG/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248799914,"owners_count":21163403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arm","decoding","embedded-systems","image-processing","jpeg-turbo","libjpeg","libjpeg-turbo","macos","opencv-python","pypy","python","python-wrapper","python2","python3","real-time","simd-optimizations","simd-parallelism","turbo-jpeg","turbojpeg","x86"],"created_at":"2024-09-24T19:20:59.915Z","updated_at":"2026-02-17T04:01:39.802Z","avatar_url":"https://github.com/lilohuang.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 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) **3.0 or later** (required for PyTurboJPEG 2.0+)\n- [numpy](https://github.com/numpy/numpy)\n\n**Important**: PyTurboJPEG 2.0+ requires libjpeg-turbo 3.0 or later as it uses the new function-based TurboJPEG 3 API. If you need to use libjpeg-turbo 2.x, please use PyTurboJPEG 1.x instead.\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# in-place decoding input.jpg to BGR array\n# here I use a 640x480 example (in practise, read the dimensions)\nin_file = open('input.jpg', 'rb')\nimg_array = np.empty((640, 480, 3), dtype=np.uint8)\nresult = jpeg.decode(in_file.read(), dst=img_array)\nin_file.close()\n\n# return value is the img_array argument value\nid(result) == id(img_array)\n# True\n\n# Optional: display the in-place array\n# cv2.imshow('img_array', img_array)\n# cv2.waitKey(0)\n\n# in-place encoding with default settings.\nbuffer_size = jpeg.buffer_size(img_array)\ndest_buf = bytearray(buffer_size)\nresult, n_byte = jpeg.encode(img_array, dst=dest_buf)\n\n# return value is the dest_buf argument value\nid(result) == id(dest_buf)\n\nout_file = open('output.jpg', 'wb')\nout_file.write(dest_buf[:n_byte])\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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flilohuang%2Fpyturbojpeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flilohuang%2Fpyturbojpeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flilohuang%2Fpyturbojpeg/lists"}