{"id":16752819,"url":"https://github.com/aalekhpatel07/debox-magick","last_synced_at":"2025-03-16T05:20:48.475Z","repository":{"id":237846342,"uuid":"795346841","full_name":"aalekhpatel07/debox-magick","owner":"aalekhpatel07","description":"Remove letterboxes and pillarboxes from images using ImageMagick","archived":false,"fork":false,"pushed_at":"2024-05-03T05:07:44.000Z","size":331,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T06:48:33.309Z","etag":null,"topics":["image-processing","imagemagick","letterbox","pillarbox"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/aalekhpatel07.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":"2024-05-03T04:45:55.000Z","updated_at":"2024-05-03T05:09:31.000Z","dependencies_parsed_at":"2024-05-03T10:49:52.566Z","dependency_job_id":"e0cd4c51-b5d5-4b6d-9fdc-95452deb0e8d","html_url":"https://github.com/aalekhpatel07/debox-magick","commit_stats":null,"previous_names":["aalekhpatel07/debox-magick"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalekhpatel07%2Fdebox-magick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalekhpatel07%2Fdebox-magick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalekhpatel07%2Fdebox-magick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aalekhpatel07%2Fdebox-magick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aalekhpatel07","download_url":"https://codeload.github.com/aalekhpatel07/debox-magick/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243827991,"owners_count":20354416,"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":["image-processing","imagemagick","letterbox","pillarbox"],"created_at":"2024-10-13T02:48:12.568Z","updated_at":"2025-03-16T05:20:48.455Z","avatar_url":"https://github.com/aalekhpatel07.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Removing letterboxes and pillarboxes from images.\n\n**Goal**: Given an image that is possibly letterboxed or pillarboxed (either by solid colors, or by blurred background), remove the letterboxing or pillarboxing and emit the cropped image to another file.\n\n## Using [Image Magick](https://imagemagick.org/)\n\n### Example\n\n\u003e [!NOTE]\n\u003e\n\u003e This example image has been obtained from [Photo by Kat Smith from Pexels](https://www.pexels.com/photo/shallow-focus-photography-of-adult-black-and-white-border-collie-551628/) and is free to use.\n\n#### Original image [1919x1281] 160K\n\n![original image of a dog without any letterboxing or pillarboxing](pexels-katlovessteve-551628.jpg)\n\n#### Letterboxed and Pillarboxed version [1919x1281] 111K\n\n![A letterboxed and pillarboxed version of the original image ](pexels-katlovessteve-551628-boxed.jpg)\n\n#### After detecting and removing the letterboxing and pillarboxing [802x802] 63K\n\n![After detecting and removing the letterboxing and pillarboxing](pexels-katlovessteve-551628-after-debox.jpg)\n\n### Solution\n\nThe following script assumes you have [Image Magick (v7+)](https://imagemagick.org/) and [ripgrep](https://github.com/BurntSushi/ripgrep) installed on your machine. You can store this file in your `/usr/local/bin/debox` and then run `sudo chmod +x /usr/local/bin/debox`. Admittedly, this script is not the fastest way to accomplish this but this is just a proof-of-concept that Image Magick can be used for this task.\n\n#### Usage\n\n```bash\ndebox image.jpg image-deboxed.jpg\n```\n\nThis will write the letterbox/pillarbox-free version of `image.jpg` to `image-deboxed.jpg`.\n\n#### Script\n\n```bash\n#!/usr/bin/env bash\n\n# Date: 2024/05/02\n# Author: Aalekh Patel (@aalekhpatel07)\n# This script uses Image Magick to remove letterboxing and pillarboxing from images\n# by detecting edge-free regions on the image using Canny edge detection.\n#\n# Usage: $ ./debox.sh foo-with-letterbox.jpg foo-output-letterbox-removed.jpg\n\nset -euxo pipefail\n\nINPUT_IMAGE=\"$1\"\nOUTPUT_IMAGE=\"$2\"\n\necho \"Removing letterboxing and pillarboxing from ${INPUT_IMAGE} and writing new image to ${OUTPUT_IMAGE}\" \u003e\u00262\n\nTEMP_IMAGE_TXT=\"${INPUT_IMAGE%%.*}.tmp.txt\"\n\n# Write txt format of canny'd image to a temporary file.\nconvert ${INPUT_IMAGE} -canny 5x1+10%+20% ${TEMP_IMAGE_TXT}\n\nHEIGHT=$(identify -ping -format \"%h\" ${INPUT_IMAGE})\nWIDTH=$(identify -ping -format \"%w\" ${INPUT_IMAGE})\n\n# These are populated by find_top_row, find_bottom_row, find_left_col, and find_right_col functions.\nZERO_ROW_FROM_TOP=0\nZERO_ROW_FROM_BOTTOM=$HEIGHT\nZERO_COL_FROM_LEFT=0\nZERO_COL_FROM_RIGHT=$WIDTH\n\nfunction find_top_row() {\n  # Find the largest block of rows from the top edge that is completely free of edges.\n  for row in $(seq 0 $HEIGHT);\n  do\n    local NUM_ZEROS=$(rg \"(\\d+),${row}: \\(0\\)  #000000  gray\\(0\\)\" --no-filename -c ${TEMP_IMAGE_TXT})\n    # entire row is zeroes (i.e. no pixels are \"edge\"-y)\n    if [[ \"${NUM_ZEROS}\" -eq ${WIDTH} ]]; then\n      # extend the box downwards.\n      if [[ \"${ZERO_ROW_FROM_TOP}\" -lt ${row} ]]; then \n        ZERO_ROW_FROM_TOP=${row}\n      fi\n    else\n      break\n    fi\n  done\n}\n\n\nfunction find_bottom_row() {\n  # Find the largest block of rows from the bottom edge that is completely free of edges.\n  HEIGHT_MINUS_ONE=$(($HEIGHT-1))\n  for row in $(seq $HEIGHT_MINUS_ONE -1 1);\n  do\n    local NUM_ZEROS=$(rg \"(\\d+),${row}: \\(0\\)  #000000  gray\\(0\\)\" --no-filename -c ${TEMP_IMAGE_TXT})\n    # entire row is zeroes (i.e. no pixels are \"edge\"-y)\n    if [[ \"${NUM_ZEROS}\" -eq ${WIDTH} ]]; then\n      # extend the box upwards.\n      if [[ \"${ZERO_ROW_FROM_BOTTOM}\" -gt ${row} ]]; then \n        ZERO_ROW_FROM_BOTTOM=${row}\n      fi\n    else\n      break\n    fi\n  done\n}\n\n\nfunction find_left_col() {\n  # Find the largest block of columns from the left edge that is completely free of edges.\n  for col in $(seq 0 $WIDTH);\n  do\n    NUM_ZEROS=$(rg \"^${col},(\\d+): \\(0\\)  #000000  gray\\(0\\)\" --no-filename -c ${TEMP_IMAGE_TXT})\n    # entire column is zeroes (i.e. no pixels are \"edge\"-y)\n    if [[ \"${NUM_ZEROS}\" -eq ${HEIGHT} ]]; then\n      # extend the box rightwards.\n      if [[ \"${ZERO_COL_FROM_LEFT}\" -lt ${col} ]]; then \n        ZERO_COL_FROM_LEFT=${col}\n      fi\n    else\n      break\n    fi\n  done\n}\n\n\nfunction find_right_col() {\n  # Find the largest block of columns from the right edge that is completely free of edges.\n  WIDTH_MINUS_ONE=$(($WIDTH-1))\n  for col in $(seq $WIDTH_MINUS_ONE -1 1);\n  do\n    NUM_ZEROS=$(rg \"^${col},(\\d+): \\(0\\)  #000000  gray\\(0\\)\" --no-filename -c ${TEMP_IMAGE_TXT})\n    # entire column is zeroes (i.e. no pixels are \"edge\"-y)\n    if [[ \"${NUM_ZEROS}\" -eq ${HEIGHT} ]]; then\n      if [[ \"${ZERO_COL_FROM_RIGHT}\" -gt ${col} ]]; then \n      # extend the box leftwards.\n        ZERO_COL_FROM_RIGHT=${col}\n      fi\n    else\n      break\n    fi\n  done\n}\n\nCROPPED_WIDTH=\nCROPPED_HEIGHT=\n\nfunction debox() {\n  # Determine the region of interest by chopping off the edge-free blocks.\n  CROPPED_WIDTH=$(($ZERO_COL_FROM_RIGHT-$ZERO_COL_FROM_LEFT))\n  CROPPED_HEIGHT=$(($ZERO_ROW_FROM_BOTTOM-$ZERO_ROW_FROM_TOP))\n  CROPPED_ROW_OFFSET=$ZERO_ROW_FROM_TOP\n  CROPPED_COL_OFFSET=$ZERO_COL_FROM_LEFT\n\n  # Extract the region of interest.\n  convert \"${INPUT_IMAGE}\"[\"${CROPPED_WIDTH}x${CROPPED_HEIGHT}+${CROPPED_COL_OFFSET}+${CROPPED_ROW_OFFSET}\"] \"${OUTPUT_IMAGE}\"\n}\n\nfind_top_row\nfind_bottom_row\nfind_left_col\nfind_right_col\n\n# If the entire image is edge-free, then swap the left/right and top/bottom back\n# since they would've effectively swapped places during the linear scan.\nif [[ ${ZERO_ROW_FROM_TOP} -gt ${ZERO_ROW_FROM_BOTTOM} ]]; then\n  ZERO_ROW_FROM_TOP_TMP=${ZERO_ROW_FROM_TOP}\n  ZERO_ROW_FROM_TOP=${ZERO_ROW_FROM_BOTTOM}\n  ZERO_ROW_FROM_BOTTOM=${ZERO_ROW_FROM_TOP_TMP}\nfi\nif [[ ${ZERO_COL_FROM_LEFT} -gt ${ZERO_COL_FROM_RIGHT} ]]; then\n  ZERO_COL_FROM_LEFT_TMP=${ZERO_COL_FROM_LEFT}\n  ZERO_COL_FROM_LEFT=${ZERO_COL_FROM_RIGHT}\n  ZERO_COL_FROM_RIGHT=${ZERO_COL_FROM_LEFT_TMP}\nfi\n\necho \"top: ${ZERO_ROW_FROM_TOP} bottom: ${ZERO_ROW_FROM_BOTTOM} left: ${ZERO_COL_FROM_LEFT} right: ${ZERO_COL_FROM_RIGHT}\" \u003e\u00262\n\ndebox\n\necho \"original: [${HEIGHT}x${WIDTH}] ${INPUT_IMAGE} -\u003e de-letterboxed/pillarboxed: [${CROPPED_HEIGHT}x${CROPPED_WIDTH}] ${OUTPUT_IMAGE}\" \u003e\u00262\n\n# Clean up the temporary txt representation\nrm ${TEMP_IMAGE_TXT}\n\n```\n\n### Adding blurred letter/pillarbox to an existing image:\n\nGiven a source image called `image.jpeg`, take two copies of it, blur one of them (to serve as the background), and resize the other (to serve as the foreground), and then finally stack them at the center into a single image.\n\n```sh\nconvert image.jpeg \\\n    \\( -clone 0 -blur 0x20 \\) \\\n    \\( -clone 0 -resize 800x800\\! \\) \\\n    -delete 0 \\\n    -gravity center \\\n    -compose over \\\n    -composite \\\n    image-boxed.jpeg\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalekhpatel07%2Fdebox-magick","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faalekhpatel07%2Fdebox-magick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalekhpatel07%2Fdebox-magick/lists"}