Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
NeverMendel committed Mar 11, 2023
1 parent efb5b10 commit f89e13d
Show file tree
Hide file tree
Showing 12 changed files with 418 additions and 1 deletion.
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:

# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"

# Maintain dependencies for Docker
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "monthly"
17 changes: 17 additions & 0 deletions .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Build Docker Image

on: [push, pull_request]

jobs:
build-image:
name: Build Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Build Docker Image
uses: docker/build-push-action@v4
with:
context: .
push: false
15 changes: 15 additions & 0 deletions .github/workflows/check-python-formatting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Check Python Formatting

on: [push, pull_request]

jobs:
check-formatting:
name: Check formatting with Black
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Check file formatting with Black
uses: psf/black@stable
with:
options: "--check --verbose"
41 changes: 41 additions & 0 deletions .github/workflows/publish-docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Publish Docker Image

on:
push:
branches:
- 'master'
tags:
- 'v*'

jobs:
publish-image:
name: Publish Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: nevermendel/heif-convert
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
43 changes: 43 additions & 0 deletions .github/workflows/publish-python-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Publish Python Package

on:
push:
tags:
- 'v*'

jobs:
publish-package:
name: Publish Package
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Set tag version
id: tag_version
run: |
tag=$(echo $GITHUB_REF | cut -d / -f 3)
echo ::set-output name=version::${tag:1}
- name: Install dependencies
run: python3 -m pip install setuptools wheel twine

- name: Build project
run: python3 setup.py sdist bdist_wheel

- name: Check build
run: python3 -m twine check dist/*

- name: Install heif-convert
run: sudo python3 setup.py install

- name: Check that tag version matches Python package version
run: |
expected="heif-convert ${{ steps.tag_version.outputs.version }}"
actual=$(heif-convert --version)
echo expected=\"$expected\"
echo actual=\"$actual\"
[[ $expected == $actual ]]
- name: Publish project
run: python3 -m twine upload dist/* -u ${{ secrets.PYPY_USERNAME }} -p ${{ secrets.PYPY_PASSWORD }} --non-interactive
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM alpine:3.17.1

RUN apk add --no-cache \
nss \
ca-certificates \
python3 \
py3-pip

# Copy current directory to /usr/src/app
ADD . /usr/app
WORKDIR /usr/app

# Create out folder
RUN mkdir -p out

# Install heif-convert
RUN pip3 install .

ENTRYPOINT ["heif-convert", "--folder", "out"]
114 changes: 113 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,114 @@
# heif-convert
Multi-Platform command line tool written in Python to convert HEIF images

Multi-Platform command line tool written in Python to convert HEIF images.

## 📝 Table of Contents

- [About](#about)
- [Installation](#installation)
- [Usage](#usage)
- [Arguments](#arguments)
- [Libraries](#libraries)
- [Supported operating systems](#supported-operating-systems)
- [License](#license)

## 📕 About <a name="about"></a>

heif-convert is a multi-platform tool written in Python to convert High Efficiency Image File (HEIF) images to jpg, png, webp, gif, tiff, bmp, or ico.

heif-convert is designed to make HEIF batch conversion easy.

## ⚙️ Installation <a name="installation"></a>

## Python repository

The easiest way to get heif-convert is through the pypi.org repository. Install it by running the following command:

```bash
pip install heif-convert
```

## Building from source

To install heif-convert from source, clone this repository and run `pip install .` as follows:

```bash
git clone https://github.com/NeverMendel/heif-convert.git
cd heif-convert
pip install .
```

## Docker image

To pull heif-convert Docker image, run:

```bash
docker pull nevermendel/heif-convert
```

## Usage

heif-convert can be used from the command line by invoking the `heif-convert` command.

Convert an HEIF image to a JPG image:

```bash
heif-convert input.heic -f jpg
```

Convert all HEIF images in the current folder to JPG images:

```bash
heif-convert *.heic -f jpg
```

### Docker image

Convert an HEIF image to PNG using the Docker image:

```bash
docker run -it -v $(pwd):/usr/app/out --rm nevermendel/heif-convert input.heic -f jpg
```

## Arguments

```
usage: heif-convert [-h] [--folder FOLDER] [-o OUTPUT]
[-f {jpg,png,webp,gif,tiff,bmp,ico}] [-q QUALITY] [-v] [-vv]
[-V]
input [input ...]
Command line tool to convert HEIF images
positional arguments:
input HEIF input file(s)
options:
-h, --help show this help message and exit
--folder FOLDER working directory (default: '.')
-o OUTPUT, --output OUTPUT
output file name excluding its extension
defaults to original file name (default: '{name}')
-f {jpg,png,webp,gif,tiff,bmp,ico}, --format {jpg,png,webp,gif,tiff,bmp,ico}
output format (default: jpg)
-q QUALITY, --quality QUALITY
output quality, integer [0, 100] (default: 90)
-v, --verbose enable verbose logging
-vv, --extra-verbose enable extra verbose logging
-V, --version show program's version number and exit
```

## Libraries

heif-convert uses the following libraries:

- [Pillow](https://github.com/python-pillow/Pillow)
- [pillow_heif](https://github.com/bigcat88/pillow_heif)

## Supported operating systems

heif-convert works on Linux, Mac OS and Windows systems. For further information refer to the [pillow_heif](https://github.com/bigcat88/pillow_heif) repository.

## License

[MIT License](LICENSE)
Empty file added heif_convert/__init__.py
Empty file.
119 changes: 119 additions & 0 deletions heif_convert/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import argparse
import os
import logging
from heif_convert._version import __version__

from PIL import Image
from pillow_heif import register_heif_opener


def parse_args():
parser = argparse.ArgumentParser(
description="Command line tool to convert HEIF images",
formatter_class=lambda prog: argparse.RawTextHelpFormatter(
"heif-convert", width=80
),
)
parser.add_argument("input", type=str, nargs="+", help="HEIF input file(s)")
parser.add_argument(
"--folder", type=str, default=".", help="working directory (default: '.')"
)
parser.add_argument(
"-o",
"--output",
type=str,
default="{name}",
help="output file name excluding its extension\n"
+ "defaults to original file name (default: '{name}')",
)
parser.add_argument(
"-f",
"--format",
type=str,
help="output format (default: jpg)",
default="jpg",
choices=["jpg", "png", "webp", "gif", "tiff", "bmp", "ico"],
)
parser.add_argument(
"-q",
"--quality",
type=int,
help="output quality, integer [0, 100] (default: 90)",
default=90,
)
parser.add_argument(
"-v",
"--verbose",
dest="verbose",
action="store_true",
help="enable verbose logging",
)
parser.add_argument(
"-vv",
"--extra-verbose",
dest="extra_verbose",
action="store_true",
help="enable extra verbose logging",
)
parser.add_argument(
"-V",
"--version",
action="version",
version="%(prog)s {version}".format(version=__version__),
)

args = parser.parse_args()

for input_file in args.input:
input_filepath = os.path.join(args.folder, input_file)
if not os.path.isfile(input_filepath):
parser.error(f"Input file '{input_filepath}' does not exist")

return args


def configure_logging(args):
logging_stream_handler = logging.StreamHandler()

# Set stream logging level based on program arguments
logging_stream_handler.setLevel(logging.WARNING)
if args.verbose:
logging_stream_handler.setLevel(logging.INFO)
if args.extra_verbose:
logging_stream_handler.setLevel(logging.DEBUG)

logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d - %(message)s",
handlers=[logging_stream_handler],
)


def main():
args = parse_args()
configure_logging(args)

logging.debug(f"heif-convert {__version__} run with arguments: {args}")

logging.debug("Registering HEIF opener")
register_heif_opener()

if not os.path.isdir(args.folder):
logging.info("Output folder not found, creating it")
os.mkdir(args.folder)
os.chdir(args.folder)

for input_file in args.input:
logging.info(f"Reading {input_file}")
image = Image.open(input_file)
output_filename = (
args.output.format(name=input_file.split(".")[0]) + "." + args.format
)
output_filepath = os.path.join(output_filename)
logging.info(f"Writing {output_filepath}")
image.save(output_filepath, quality=args.quality)
print(f"Wrote {output_filepath}")


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions heif_convert/_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.0.0"
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Pillow
pillow-heif
Loading

0 comments on commit f89e13d

Please sign in to comment.