diff --git a/README.md b/README.md index e2f787c..ab4fc6d 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,37 @@ -# **heic-to-jpg** -converting heic files using the internet is cumbersome so i made this not-so-intuitive way of converting things +# **SnapShift** +Previously *heic-to-jpg*, converting heic files using the internet is cumbersome and so i made this *now intuitive* way of converting `.heic` files to multiple image formats. # **Installation** -To run this script, you will need to install the required libraries listed in the `requirements.txt` file. You can do this using pip by running the following command in your terminal: - -``` -pip install -r requirements.txt # for Windows -``` - -Alternatively, you can manually install the required libraries by running the following command for each library: - -``` -pip install -``` - -# **Usage** -To use the script, run the following command in your terminal: - -``` -python3 converter.py -``` -Choose the folder with your HEIC file/s, and it will automatically place the converted HEIC files to the same path destination of your HEIC file/s folder. +1. Download the `SnapShift.exe` file +2. Choose your Target Folder with the .heic images +3. Choose your Destination Folder for the converted images +4. Choose what image type you want your .heic file to be converted +5. Convert and wait for it to be finished. # **Contributing** + Contributions to this project are welcome! To contribute, please fork this repository, make your changes, and submit a pull request. Before submitting a pull request, please make sure that your changes are well-tested and adhere to the PEP 8 style guide. +To run this script, you will need to install the required libraries listed in the `requirements.txt` file. + +1. Clone the repository + ``` + git clone https://github.com/louispawaon/snapshift.git + ``` +2. Create a virtual environment + ``` + cd SnapShift + python3 -m venv venv + ``` +3. Install `requirements.txt` + ``` + pip install -r requirements.txt + ``` +4. Run the script + ``` + cd src + python3 converter.py + ``` + # **Issues** -If you encounter any issues while using this script, please report them by creating a new [issue](https://github.com/louispawaon/heic-to-jpg/issues) in the issue tracker. When reporting an issue, please include a detailed description of the problem, along with any relevant error messages and steps to reproduce the issue. \ No newline at end of file +If you encounter any issues while using this script, please report them by creating a new [issue](https://github.com/louispawaon/snapshift/issues) in the issue tracker. When reporting an issue, please include a detailed description of the problem, along with any relevant error messages and steps to reproduce the issue. \ No newline at end of file diff --git a/converter.py b/converter.py deleted file mode 100644 index ce16eaa..0000000 --- a/converter.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -from PIL import Image -import pillow_heif -from PyQt5.QtWidgets import QApplication, QFileDialog, QMessageBox - - -def convert_to_jpg(input_path, output_path): - for filename in os.listdir(input_path): - if filename.lower().endswith((".heic", ".heif")): - filepath = os.path.join(input_path, filename) - heif_file = pillow_heif.read_heif(filepath) - image = Image.frombytes( - heif_file.mode, - heif_file.size, - heif_file.data, - "raw", - ) - output_path_new = os.path.join( - output_path, os.path.splitext(filename)[0] + ".jpg" - ) - image.save(output_path_new) - - -def choose_folder(): - input_path = QFileDialog.getExistingDirectory(None, "Choose a Folder") - return input_path - - -def main(): - input_path = choose_folder() - if input_path: - output_path = os.path.join(os.path.dirname(input_path), "converted_jpgs") - os.makedirs(output_path, exist_ok=True) - try: - convert_to_jpg(input_path, output_path) - message_box = QMessageBox() - message_box.setWindowTitle("Success") - message_box.setText("Conversion complete.") - message_box.setIcon(QMessageBox.Information) - message_box.exec_() - except Exception as e: - message_box = QMessageBox() - message_box.setWindowTitle("Error") - message_box.setText(f"An error occurred: {e}") - message_box.setIcon(QMessageBox.Warning) - message_box.exec_() - else: - message_box = QMessageBox() - message_box.setWindowTitle("Error") - message_box.setText("No folder selected.") - message_box.setIcon(QMessageBox.Warning) - message_box.exec_() - - -if __name__ == "__main__": - app = QApplication([]) - main() diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index ed9c20a..0000000 --- a/poetry.lock +++ /dev/null @@ -1,219 +0,0 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. - -[[package]] -name = "pillow" -version = "9.5.0" -description = "Python Imaging Library (Fork)" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "pillow-heif" -version = "0.10.1" -description = "Python interface for libheif library" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pillow_heif-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2e34110c906035f9902bb7dee964384e33b45c4545cee0fc4f78bd06b6cffbe0"}, - {file = "pillow_heif-0.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:9d67655cde69eb76f7b5a3f3b3069998d43c9cd157a1e41997fe165a44614401"}, - {file = "pillow_heif-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd3b2bfa20f3af072c1a1fedbdee441b71972969e09efc6b0f9789b540d51899"}, - {file = "pillow_heif-0.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:091e43a45b1ed155c65a3a99252ba5d1ea7ba9ba7e9880afa06997533abe4875"}, - {file = "pillow_heif-0.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd01437bca86e61b252a0e730c2181b3dd3bfb57367c0473a8dca6db53be5818"}, - {file = "pillow_heif-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2229077a834182477cfb8f665c4c42ce9766d90d746d74c7ab6d48945c8a6992"}, - {file = "pillow_heif-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f62617d91e6656535fde6ddb61f413c27e81f2d58eb38201b62982a05a729acd"}, - {file = "pillow_heif-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f98a5c77626bfb1dfdc83939fe44eb11ab721edfd4ca516e8e9b8e3c0dcfbe13"}, - {file = "pillow_heif-0.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c791917a9e286f3d692f5c162dedf07e65ebab18c4df7ad7a5a109d395aaca9"}, - {file = "pillow_heif-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b21d19372d9a1cc22a6e639cc929bc3abae7f701ee7c8b66bad5302f36977eef"}, - {file = "pillow_heif-0.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c57bbb1a1aabb88efa72ba24300a3df733826ed8892d5bbcc8317b4262e95a03"}, - {file = "pillow_heif-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d4b04bf35280f7d895ba783c4b7f7e3d0f139c99fd736e1831d2cfe06a41c10"}, - {file = "pillow_heif-0.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a2722a220d898cbcd1e3d6bcb669a28cfcb240d05f41bcd57d4b78af991b32cc"}, - {file = "pillow_heif-0.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae92c3e9b348e367122b140fd7a744bdb087c551ac00efc2b486a410569d00f"}, - {file = "pillow_heif-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:400b25a1110ef5dfe394255646bae5318779d2ec4c787792bd5ba72956df628f"}, - {file = "pillow_heif-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:16db680b312ea684b3b88a3f97b3b122df48e12a057351c3ed1f435dd0a634d2"}, - {file = "pillow_heif-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db7363f190faeda67b15cf774fddf6c658a5681abb8b9860dcbc47cc85d668f8"}, - {file = "pillow_heif-0.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:7b84073e2997f34062751e8dd0a644e3e8f6fd952265edfe7ee021531a939018"}, - {file = "pillow_heif-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ef1c87acea720edf784fa3da77d3292f288de1c9f40e9808f4c6837dd167afc3"}, - {file = "pillow_heif-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dae1ca05c818abc31bbc259a17554c3dd9faca4d79618f06f0cc2439320c4f58"}, - {file = "pillow_heif-0.10.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3dece6099058422ab7a66b713e9fc3ea4e21946a95442c276956825602a0782c"}, - {file = "pillow_heif-0.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8173d2843207a1c3265e382e7dcb02d8d5f882b5cd8ab9a1701c5bf47639ae22"}, - {file = "pillow_heif-0.10.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0ed8652a520a46aa936b816bb3fcd445aba5ae6678f444927dcd6e7f831e02db"}, - {file = "pillow_heif-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:da5c734c9510ccb05f42199bedb6b0f126f9e8447e3bde3ad03f3882817ad08c"}, - {file = "pillow_heif-0.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:27c1b4e388fde47f690a0b8e4299a8da57329a35e1924444028865e0efd20430"}, - {file = "pillow_heif-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05406e07d6640e122729e249ad6a2bf28c1aabe0dde0a71217ad54c36854e0e9"}, - {file = "pillow_heif-0.10.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffa99da11b0328dc483976d5c4e62cccc75903e0bcc861e3d9fbce2752f0dff5"}, - {file = "pillow_heif-0.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd6f4f01006dfa5cfefd1e960763e2f3bd829e0c6e6d8202462fc3f7d0b91dfd"}, - {file = "pillow_heif-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ea6cf2255179bb667b75b834845083f23959fc3873c444a15f54cad415e501dd"}, - {file = "pillow_heif-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bc12fc70de7f59a313678255b9abc7acd4915032cdbdb887a402f1e6c632e95d"}, - {file = "pillow_heif-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50cbb535e9b776bd327d7344e22bec1f7457ae587487189a136339cf90952a99"}, - {file = "pillow_heif-0.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:82143407c590122e1d36bf674d7d589d20ed76fac243a65d1704e6b0fbc14dde"}, - {file = "pillow_heif-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4bf6abce62e934e33dbd5cf8528c76c746397116a87128b913278554eb840c3b"}, - {file = "pillow_heif-0.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:5909585d1878dfe214a7bc6ae502ce6e1ee99cab88dd0669714c2d524f8509da"}, - {file = "pillow_heif-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95c0e83ef5237b18ae5e4adc5e5c9261b23c13704abedf1bbb46cc44d086312a"}, - {file = "pillow_heif-0.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:158dc0eabaadb13240d2bc14ce11047a661a4748e56423a5346c4ffa9831e0e3"}, - {file = "pillow_heif-0.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:856a4f46a689bc037c0e51b8ceae1e7944907a2c8a3767dd4d72c9f781ed82b7"}, - {file = "pillow_heif-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41a75fbf044db03d3e5d64c8288b7ea3ba4b9575ff1078f1df814936f15d11b7"}, - {file = "pillow_heif-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e9745aab7ed2bb0e53548e1e2c906721b0bc76adedeb17e661ec9ccbd8b698fd"}, - {file = "pillow_heif-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ade9dbfbc5653fcf345fd8db75fb4fec603b521b1a832f091a809258d2232b5"}, - {file = "pillow_heif-0.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:41610fae8e2494f605b7b5c2508f6c2688227a7cd3f2c71e1fff966fd9476297"}, - {file = "pillow_heif-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a49c5671f74d8d58e4a0d507a3cdbd37c28693f5ad50b5bed5983a2b693e572a"}, - {file = "pillow_heif-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de3a2929e509a93981866fb9ec2f313ee349312009ca50ed1ca999c4039c31e1"}, - {file = "pillow_heif-0.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e50cab15f2531ea5bdda9b15e5f2d05bf023b607e4322bc600dd18e3783757"}, - {file = "pillow_heif-0.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:dc143d3f61b7a7d28f4200be9cdcf0149b5da44511d8faacb4778a9dc264e900"}, - {file = "pillow_heif-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c57dc8496e59d4d9b8f79e66be148e5c898704b7bbd65531d69352bce2e820f0"}, - {file = "pillow_heif-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37dd748836c8d5d82ef5395cd8aee523dba5bc0c6a77353baacf7868de41eec3"}, - {file = "pillow_heif-0.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28a3872f66d55d74ea4c18f1460ccba1bae20874100331b58dae6bbc240c63a5"}, - {file = "pillow_heif-0.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9c6880056df5898cada6f65b5dc6ba8259da1b570491c18da867420f32314512"}, - {file = "pillow_heif-0.10.1.tar.gz", hash = "sha256:af9bd9d8fc189451edb193f321214207bf890d0ac80ac697056def39fec7565d"}, -] - -[package.dependencies] -pillow = ">=8.4.0" - -[package.extras] -dev = ["coverage", "defusedxml", "numpy", "opencv-python (==4.7.0.72)", "packaging", "pre-commit", "pylint", "pympler", "pytest"] -docs = ["sphinx (>=4.4)", "sphinx-issues (>=3.0.1)", "sphinx-rtd-theme (>=1.0)"] -tests = ["defusedxml", "numpy", "packaging", "pympler", "pytest"] -tests-min = ["defusedxml", "packaging", "pytest"] - -[[package]] -name = "pyqt5" -version = "5.15.10" -description = "Python bindings for the Qt cross platform application toolkit" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "PyQt5-5.15.10-cp37-abi3-macosx_10_13_x86_64.whl", hash = "sha256:93288d62ebd47b1933d80c27f5d43c7c435307b84d480af689cef2474e87e4c8"}, - {file = "PyQt5-5.15.10-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:862cea3be95b4b0a2b9678003b3a18edf7bd5eafd673860f58820f246d4bf616"}, - {file = "PyQt5-5.15.10-cp37-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:b89478d16d4118664ff58ed609e0a804d002703c9420118de7e4e70fa1cb5486"}, - {file = "PyQt5-5.15.10-cp37-abi3-win32.whl", hash = "sha256:ff99b4f91aa8eb60510d5889faad07116d3340041916e46c07d519f7cad344e1"}, - {file = "PyQt5-5.15.10-cp37-abi3-win_amd64.whl", hash = "sha256:501355f327e9a2c38db0428e1a236d25ebcb99304cd6e668c05d1188d514adec"}, - {file = "PyQt5-5.15.10.tar.gz", hash = "sha256:d46b7804b1b10a4ff91753f8113e5b5580d2b4462f3226288e2d84497334898a"}, -] - -[package.dependencies] -PyQt5-Qt5 = ">=5.15.2" -PyQt5-sip = ">=12.13,<13" - -[[package]] -name = "pyqt5-qt5" -version = "5.15.11" -description = "The subset of a Qt installation needed by PyQt5." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "PyQt5_Qt5-5.15.11-1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9bb0d816de8c003ce41881e39fe5d64c2cdf5e8ca96b6c016c34f8e0bdc30768"}, - {file = "PyQt5_Qt5-5.15.11-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:109c418d221538751e4d7755a81c978ee31abbd65facb3f1f361dca74a1b758a"}, - {file = "PyQt5_Qt5-5.15.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3cccb21942eb49d21fb0193f28e3e8ae3d35395f158e8a9d4d58e23efa3a2ea7"}, -] - -[[package]] -name = "pyqt5-sip" -version = "12.13.0" -description = "The sip module support for PyQt5" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "PyQt5_sip-12.13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a7e3623b2c743753625c4650ec7696362a37fb36433b61824cf257f6d3d43cca"}, - {file = "PyQt5_sip-12.13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6e4ac714252370ca037c7d609da92388057165edd4f94e63354f6d65c3ed9d53"}, - {file = "PyQt5_sip-12.13.0-cp310-cp310-win32.whl", hash = "sha256:d5032da3fff62da055104926ffe76fd6044c1221f8ad35bb60804bcb422fe866"}, - {file = "PyQt5_sip-12.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:9a8cdd6cb66adcbe5c941723ed1544eba05cf19b6c961851b58ccdae1c894afb"}, - {file = "PyQt5_sip-12.13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f85fb633a522f04e48008de49dce1ff1d947011b48885b8428838973fbca412"}, - {file = "PyQt5_sip-12.13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec60162e034c42fb99859206d62b83b74f987d58937b3a82bdc07b5c3d190dec"}, - {file = "PyQt5_sip-12.13.0-cp311-cp311-win32.whl", hash = "sha256:205cd449d08a2b024a468fb6100cd7ed03e946b4f49706f508944006f955ae1a"}, - {file = "PyQt5_sip-12.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:1c8371682f77852256f1f2d38c41e2e684029f43330f0635870895ab01c02f6c"}, - {file = "PyQt5_sip-12.13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7fe3375b508c5bc657d73b9896bba8a768791f1f426c68053311b046bcebdddf"}, - {file = "PyQt5_sip-12.13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:773731b1b5ab1a7cf5621249f2379c95e3d2905e9bd96ff3611b119586daa876"}, - {file = "PyQt5_sip-12.13.0-cp312-cp312-win32.whl", hash = "sha256:fb4a5271fa3f6bc2feb303269a837a95a6d8dd16be553aa40e530de7fb81bfdf"}, - {file = "PyQt5_sip-12.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:3a4498f3b1b15f43f5d12963accdce0fd652b0bcaae6baf8008663365827444c"}, - {file = "PyQt5_sip-12.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b984c2620a7a7eaf049221b09ae50a345317add2624c706c7d2e9e6632a9587"}, - {file = "PyQt5_sip-12.13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3188a06956aef86f604fb0d14421a110fad70d2a9e943dbacbfc3303f651dade"}, - {file = "PyQt5_sip-12.13.0-cp38-cp38-win32.whl", hash = "sha256:108a15f603e1886988c4b0d9d41cb74c9f9815bf05cefc843d559e8c298a10ce"}, - {file = "PyQt5_sip-12.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:db228cd737f5cbfc66a3c3e50042140cb80b30b52edc5756dbbaa2346ec73137"}, - {file = "PyQt5_sip-12.13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5338773bbaedaa4f16a73c142fb23cc18c327be6c338813af70260b756c7bc92"}, - {file = "PyQt5_sip-12.13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:29fa9cc964517c9fc3f94f072b9a2aeef4e7a2eda1879cb835d9e06971161cdf"}, - {file = "PyQt5_sip-12.13.0-cp39-cp39-win32.whl", hash = "sha256:96414c93f3d33963887cf562d50d88b955121fbfd73f937c8eca46643e77bf61"}, - {file = "PyQt5_sip-12.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:bbc7cd498bf19e0862097be1ad2243e824dea56726f00c11cff1b547c2d31d01"}, - {file = "PyQt5_sip-12.13.0.tar.gz", hash = "sha256:7f321daf84b9c9dbca61b80e1ef37bdaffc0e93312edae2cd7da25b953971d91"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.11" -content-hash = "456f70d5e3c7c0f5723ee808787d2768126911c9bf54baf91dc5822e68256ca5" diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 358fcbf..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -[tool.poetry] -name = "heic-to-jpg" -version = "0.1.0" -description = "converting heic files is tiring using the internet, so i made one myself" -authors = ["louispawaon "] -readme = "README.md" -packages = [{include = "heic_to_jpg"}] - -[tool.poetry.dependencies] -python = "^3.11" -pillow = "^9.5.0" -pillow-heif = "^0.10.1" -pyqt5 = "^5.15.9" - - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt index 4d4525c..b7d66bb 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/src/assets/icon.ico b/src/assets/icon.ico new file mode 100644 index 0000000..08f6c53 Binary files /dev/null and b/src/assets/icon.ico differ diff --git a/src/converter.py b/src/converter.py new file mode 100644 index 0000000..5b52970 --- /dev/null +++ b/src/converter.py @@ -0,0 +1,182 @@ +import sys +import os +from PIL import Image +import pillow_heif +from PySide6.QtWidgets import ( + QApplication, + QMainWindow, + QPushButton, + QFileDialog, + QLabel, + QVBoxLayout, + QHBoxLayout, + QWidget, + QProgressBar, + QListWidget, + QMessageBox, + QComboBox, +) +from PySide6.QtCore import Qt, QThread, Signal +from PySide6.QtGui import QIcon + + +class ConversionThread(QThread): + progress = Signal(int) + finished = Signal() + error = Signal(str) + + def __init__(self, input_path, output_path, output_format): + super().__init__() + self.input_path = input_path + self.output_path = output_path + self.output_format = output_format + + def run(self): + try: + files = [ + f + for f in os.listdir(self.input_path) + if f.lower().endswith((".heic", ".heif")) + ] + total_files = len(files) + + for i, filename in enumerate(files, 1): + filepath = os.path.join(self.input_path, filename) + heif_file = pillow_heif.read_heif(filepath) + image = Image.frombytes( + heif_file.mode, heif_file.size, heif_file.data, "raw" + ) + output_filename = ( + os.path.splitext(filename)[0] + f".{self.output_format.lower()}" + ) + output_path_new = os.path.join(self.output_path, output_filename) + if self.output_format.upper() == "JPG": + image.save(output_path_new, format="JPEG") + else: + image.save(output_path_new, format=self.output_format.upper()) + self.progress.emit(int((i / total_files) * 100)) + + self.finished.emit() + except Exception as e: + self.error.emit(str(e)) + + +class MainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("SnapShift") + self.setGeometry(100, 100, 600, 400) + self.setWindowIcon(QIcon("src/assets/icon.ico")) + main_layout = QVBoxLayout() + + # Input folder selection + input_layout = QHBoxLayout() + self.input_label = QLabel("Input Folder:") + self.input_path = QLabel("Not selected") + self.input_button = QPushButton("Browse") + self.input_button.clicked.connect(self.choose_input_folder) + input_layout.addWidget(self.input_label) + input_layout.addWidget(self.input_path) + input_layout.addWidget(self.input_button) + + # Output folder selection + output_layout = QHBoxLayout() + self.output_label = QLabel("Output Folder:") + self.output_path = QLabel("Not selected") + self.output_button = QPushButton("Browse") + self.output_button.clicked.connect(self.choose_output_folder) + output_layout.addWidget(self.output_label) + output_layout.addWidget(self.output_path) + output_layout.addWidget(self.output_button) + + # Output format selection + format_layout = QHBoxLayout() + self.format_label = QLabel("Output Format:") + self.format_combo = QComboBox() + self.format_combo.addItems(["JPG", "PNG", "WebP", "BMP", "TIFF"]) + format_layout.addWidget(self.format_label) + format_layout.addWidget(self.format_combo) + + # File list + self.file_list = QListWidget() + + # Progress bar + self.progress_bar = QProgressBar() + + # Convert button + self.convert_button = QPushButton("Convert") + self.convert_button.clicked.connect(self.start_conversion) + self.convert_button.setEnabled(False) + + main_layout.addLayout(input_layout) + main_layout.addLayout(output_layout) + main_layout.addLayout(format_layout) + main_layout.addWidget(self.file_list) + main_layout.addWidget(self.progress_bar) + main_layout.addWidget(self.convert_button) + + central_widget = QWidget() + central_widget.setLayout(main_layout) + self.setCentralWidget(central_widget) + + def choose_input_folder(self): + folder = QFileDialog.getExistingDirectory(self, "Choose Input Folder") + if folder: + self.input_path.setText(folder) + self.update_file_list() + self.check_convert_button() + + def choose_output_folder(self): + folder = QFileDialog.getExistingDirectory(self, "Choose Output Folder") + if folder: + self.output_path.setText(folder) + self.check_convert_button() + + def update_file_list(self): + self.file_list.clear() + input_folder = self.input_path.text() + if os.path.isdir(input_folder): + files = [ + f + for f in os.listdir(input_folder) + if f.lower().endswith((".heic", ".heif")) + ] + self.file_list.addItems(files) + + def check_convert_button(self): + self.convert_button.setEnabled( + os.path.isdir(self.input_path.text()) + and os.path.isdir(self.output_path.text()) + and self.file_list.count() > 0 + ) + + def start_conversion(self): + output_format = self.format_combo.currentText() + self.conversion_thread = ConversionThread( + self.input_path.text(), self.output_path.text(), output_format + ) + self.conversion_thread.progress.connect(self.update_progress) + self.conversion_thread.finished.connect(self.conversion_finished) + self.conversion_thread.error.connect(self.conversion_error) + + self.convert_button.setEnabled(False) + self.progress_bar.setValue(0) + self.conversion_thread.start() + + def update_progress(self, value): + self.progress_bar.setValue(value) + + def conversion_finished(self): + QMessageBox.information(self, "Success", "Conversion completed successfully!") + self.convert_button.setEnabled(True) + + def conversion_error(self, error_message): + QMessageBox.warning(self, "Error", f"An error occurred: {error_message}") + self.convert_button.setEnabled(True) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = MainWindow() + window.show() + sys.exit(app.exec())