diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..efa1acd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# Ignore any other files further up in the file system +root = true + +# Configuration for all files +[*] +indent_style = space +indent_size = 4 +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..adf4892 --- /dev/null +++ b/.flake8 @@ -0,0 +1,11 @@ +[flake8] +ignore = + E203, + W503, + F821, + F722 + +exclude = + bin/ + +max-line-length = 88 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07c73cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,226 @@ +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[co] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +pytestdebug.log + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ +doc/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +Pipfile.lock + +# poetry +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +# .env +.env/ +.venv/ +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +pythonenv* + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# operating system-related files +# file properties cache/storage on macOS +*.DS_Store +# thumbnail cache on Windows +Thumbs.db + +# profiling data +.prof + + +### Windows ### +# Windows thumbnail cache files +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### VisualStudioCode ### +.vscode/* +*.code-workspace + +### User preferences ### +# Blender files +*.blend +*.blend1 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..079ee7b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog + +## [1.4.0](https://github.com/Yeetus3141/ImagePaste/compare/v1.3.2...v1.4.0) (2021-06-10) +- Now Supports X11 Clipboard on Linux platform, all thanks to [@thanhph111](https://github.com/thanhph111) + +## [1.3.2](https://github.com/Yeetus3141/ImagePaste/compare/v1.3.1...v1.3.2) (2021-04-16) +- Updated image naming scheme, now with timestamps, preventing overwriting of saved images. +- Merged separate build versions of ImagePaste for Blender version below 2.93a and above into one. + +## [1.3.1](https://github.com/Yeetus3141/ImagePaste/compare/v1.3.0...v1.3.1) (2021-03-14) +- Fixed issue with the copy to clipboard feature where it didn't work as intended for certain cases. + +## [1.3.0](https://github.com/Yeetus3141/ImagePaste/compare/v1.1.0...v1.3.0) (2021-03-12) +- Image(s) can be pasted directly into the Node Editor as Image Texture Node(s), using `Node Editor > Context Menu (Right Click) > Paste Images From Clipboard` or `Ctrl + Shift + V` +- Images can now be copied to clipboard. In the `Image Editor > Image > Copy To Clipboard`, or `Ctrl + Shift + C`. These images are also saved along with other images in the set directory. + +## 1.2.0 (2021-02-06) +- Paste image from clipboard directly as a plane onto the viewport `Ctrl + Shift + Alt + V`. +- Supports image(s) copied from file explorer in Windows. +- Multiple images can now be pasted at the same time if multiple images are copied from the file explorer (only for Windows). +- Fixed an issue where images where saved with the same name in the default directory even with different blender sessions and led to different images being loaded from what was pasted +- Added icons for the buttons + +## [1.1.0](https://github.com/Yeetus3141/ImagePaste/compare/v1.0.0...v1.1.0) (2021-01-06) +- Improved error management. +- The images are now saved in the same folder as the .blend file, in a newly created subfolder. If the blend file is not saved, it uses the directory set in preferences or the default temp directory, which might raise permission error. This feature can be toggled via addon preferences. +- Improved the UI in preferences. + +## [1.0.0](https://github.com/Yeetus3141/ImagePaste/releases/tag/v1.0.0) (2021-01-04) +- Initial release. diff --git a/PIL/__pycache__/BdfFontFile.cpython-37.pyc b/PIL/__pycache__/BdfFontFile.cpython-37.pyc deleted file mode 100644 index dbc37e5..0000000 Binary files a/PIL/__pycache__/BdfFontFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/BlpImagePlugin.cpython-37.pyc b/PIL/__pycache__/BlpImagePlugin.cpython-37.pyc deleted file mode 100644 index 1edea2e..0000000 Binary files a/PIL/__pycache__/BlpImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/BmpImagePlugin.cpython-37.pyc b/PIL/__pycache__/BmpImagePlugin.cpython-37.pyc deleted file mode 100644 index 9e2b2d2..0000000 Binary files a/PIL/__pycache__/BmpImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/BufrStubImagePlugin.cpython-37.pyc b/PIL/__pycache__/BufrStubImagePlugin.cpython-37.pyc deleted file mode 100644 index 4011f22..0000000 Binary files a/PIL/__pycache__/BufrStubImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ContainerIO.cpython-37.pyc b/PIL/__pycache__/ContainerIO.cpython-37.pyc deleted file mode 100644 index 066cb25..0000000 Binary files a/PIL/__pycache__/ContainerIO.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/CurImagePlugin.cpython-37.pyc b/PIL/__pycache__/CurImagePlugin.cpython-37.pyc deleted file mode 100644 index 8d75ad9..0000000 Binary files a/PIL/__pycache__/CurImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/DcxImagePlugin.cpython-37.pyc b/PIL/__pycache__/DcxImagePlugin.cpython-37.pyc deleted file mode 100644 index 23e9cf5..0000000 Binary files a/PIL/__pycache__/DcxImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/DdsImagePlugin.cpython-37.pyc b/PIL/__pycache__/DdsImagePlugin.cpython-37.pyc deleted file mode 100644 index ca35a85..0000000 Binary files a/PIL/__pycache__/DdsImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/EpsImagePlugin.cpython-37.pyc b/PIL/__pycache__/EpsImagePlugin.cpython-37.pyc deleted file mode 100644 index 5d73023..0000000 Binary files a/PIL/__pycache__/EpsImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ExifTags.cpython-37.pyc b/PIL/__pycache__/ExifTags.cpython-37.pyc deleted file mode 100644 index f86d9c2..0000000 Binary files a/PIL/__pycache__/ExifTags.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/FitsStubImagePlugin.cpython-37.pyc b/PIL/__pycache__/FitsStubImagePlugin.cpython-37.pyc deleted file mode 100644 index fbc3cc9..0000000 Binary files a/PIL/__pycache__/FitsStubImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/FliImagePlugin.cpython-37.pyc b/PIL/__pycache__/FliImagePlugin.cpython-37.pyc deleted file mode 100644 index bd21908..0000000 Binary files a/PIL/__pycache__/FliImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/FontFile.cpython-37.pyc b/PIL/__pycache__/FontFile.cpython-37.pyc deleted file mode 100644 index 8627a71..0000000 Binary files a/PIL/__pycache__/FontFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/FpxImagePlugin.cpython-37.pyc b/PIL/__pycache__/FpxImagePlugin.cpython-37.pyc deleted file mode 100644 index 0823039..0000000 Binary files a/PIL/__pycache__/FpxImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/FtexImagePlugin.cpython-37.pyc b/PIL/__pycache__/FtexImagePlugin.cpython-37.pyc deleted file mode 100644 index c6f9cd2..0000000 Binary files a/PIL/__pycache__/FtexImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/GbrImagePlugin.cpython-37.pyc b/PIL/__pycache__/GbrImagePlugin.cpython-37.pyc deleted file mode 100644 index 7b9e024..0000000 Binary files a/PIL/__pycache__/GbrImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/GdImageFile.cpython-37.pyc b/PIL/__pycache__/GdImageFile.cpython-37.pyc deleted file mode 100644 index 8a673cc..0000000 Binary files a/PIL/__pycache__/GdImageFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/GifImagePlugin.cpython-37.pyc b/PIL/__pycache__/GifImagePlugin.cpython-37.pyc deleted file mode 100644 index 66ddfdc..0000000 Binary files a/PIL/__pycache__/GifImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/GimpGradientFile.cpython-37.pyc b/PIL/__pycache__/GimpGradientFile.cpython-37.pyc deleted file mode 100644 index c864fdd..0000000 Binary files a/PIL/__pycache__/GimpGradientFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/GimpPaletteFile.cpython-37.pyc b/PIL/__pycache__/GimpPaletteFile.cpython-37.pyc deleted file mode 100644 index b5724b1..0000000 Binary files a/PIL/__pycache__/GimpPaletteFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/GribStubImagePlugin.cpython-37.pyc b/PIL/__pycache__/GribStubImagePlugin.cpython-37.pyc deleted file mode 100644 index 3623c68..0000000 Binary files a/PIL/__pycache__/GribStubImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/Hdf5StubImagePlugin.cpython-37.pyc b/PIL/__pycache__/Hdf5StubImagePlugin.cpython-37.pyc deleted file mode 100644 index 0d99738..0000000 Binary files a/PIL/__pycache__/Hdf5StubImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/IcnsImagePlugin.cpython-37.pyc b/PIL/__pycache__/IcnsImagePlugin.cpython-37.pyc deleted file mode 100644 index 5b92756..0000000 Binary files a/PIL/__pycache__/IcnsImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/IcoImagePlugin.cpython-37.pyc b/PIL/__pycache__/IcoImagePlugin.cpython-37.pyc deleted file mode 100644 index 0b395b7..0000000 Binary files a/PIL/__pycache__/IcoImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImImagePlugin.cpython-37.pyc b/PIL/__pycache__/ImImagePlugin.cpython-37.pyc deleted file mode 100644 index c685d0d..0000000 Binary files a/PIL/__pycache__/ImImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/Image.cpython-37.pyc b/PIL/__pycache__/Image.cpython-37.pyc deleted file mode 100644 index 64dd64b..0000000 Binary files a/PIL/__pycache__/Image.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageChops.cpython-37.pyc b/PIL/__pycache__/ImageChops.cpython-37.pyc deleted file mode 100644 index 88c2cc4..0000000 Binary files a/PIL/__pycache__/ImageChops.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageCms.cpython-37.pyc b/PIL/__pycache__/ImageCms.cpython-37.pyc deleted file mode 100644 index ff01ffd..0000000 Binary files a/PIL/__pycache__/ImageCms.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageColor.cpython-37.pyc b/PIL/__pycache__/ImageColor.cpython-37.pyc deleted file mode 100644 index fd114c3..0000000 Binary files a/PIL/__pycache__/ImageColor.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageDraw.cpython-37.pyc b/PIL/__pycache__/ImageDraw.cpython-37.pyc deleted file mode 100644 index 735665f..0000000 Binary files a/PIL/__pycache__/ImageDraw.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageDraw2.cpython-37.pyc b/PIL/__pycache__/ImageDraw2.cpython-37.pyc deleted file mode 100644 index b058bb9..0000000 Binary files a/PIL/__pycache__/ImageDraw2.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageEnhance.cpython-37.pyc b/PIL/__pycache__/ImageEnhance.cpython-37.pyc deleted file mode 100644 index 021fb96..0000000 Binary files a/PIL/__pycache__/ImageEnhance.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageFile.cpython-37.pyc b/PIL/__pycache__/ImageFile.cpython-37.pyc deleted file mode 100644 index 0894bb4..0000000 Binary files a/PIL/__pycache__/ImageFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageFilter.cpython-37.pyc b/PIL/__pycache__/ImageFilter.cpython-37.pyc deleted file mode 100644 index 62e7e92..0000000 Binary files a/PIL/__pycache__/ImageFilter.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageFont.cpython-37.pyc b/PIL/__pycache__/ImageFont.cpython-37.pyc deleted file mode 100644 index 8ca3d73..0000000 Binary files a/PIL/__pycache__/ImageFont.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageGrab.cpython-37.pyc b/PIL/__pycache__/ImageGrab.cpython-37.pyc deleted file mode 100644 index 9452048..0000000 Binary files a/PIL/__pycache__/ImageGrab.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageMath.cpython-37.pyc b/PIL/__pycache__/ImageMath.cpython-37.pyc deleted file mode 100644 index 1bc4b7f..0000000 Binary files a/PIL/__pycache__/ImageMath.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageMode.cpython-37.pyc b/PIL/__pycache__/ImageMode.cpython-37.pyc deleted file mode 100644 index 1a7c25b..0000000 Binary files a/PIL/__pycache__/ImageMode.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageMorph.cpython-37.pyc b/PIL/__pycache__/ImageMorph.cpython-37.pyc deleted file mode 100644 index a5e2b1b..0000000 Binary files a/PIL/__pycache__/ImageMorph.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageOps.cpython-37.pyc b/PIL/__pycache__/ImageOps.cpython-37.pyc deleted file mode 100644 index 25e0293..0000000 Binary files a/PIL/__pycache__/ImageOps.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImagePalette.cpython-37.pyc b/PIL/__pycache__/ImagePalette.cpython-37.pyc deleted file mode 100644 index fe71b17..0000000 Binary files a/PIL/__pycache__/ImagePalette.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImagePath.cpython-37.pyc b/PIL/__pycache__/ImagePath.cpython-37.pyc deleted file mode 100644 index f5a2083..0000000 Binary files a/PIL/__pycache__/ImagePath.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageQt.cpython-37.pyc b/PIL/__pycache__/ImageQt.cpython-37.pyc deleted file mode 100644 index f8ea885..0000000 Binary files a/PIL/__pycache__/ImageQt.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageSequence.cpython-37.pyc b/PIL/__pycache__/ImageSequence.cpython-37.pyc deleted file mode 100644 index 1bf1cf2..0000000 Binary files a/PIL/__pycache__/ImageSequence.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageShow.cpython-37.pyc b/PIL/__pycache__/ImageShow.cpython-37.pyc deleted file mode 100644 index 10b5fe1..0000000 Binary files a/PIL/__pycache__/ImageShow.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageStat.cpython-37.pyc b/PIL/__pycache__/ImageStat.cpython-37.pyc deleted file mode 100644 index c093a16..0000000 Binary files a/PIL/__pycache__/ImageStat.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageTk.cpython-37.pyc b/PIL/__pycache__/ImageTk.cpython-37.pyc deleted file mode 100644 index eb67498..0000000 Binary files a/PIL/__pycache__/ImageTk.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageTransform.cpython-37.pyc b/PIL/__pycache__/ImageTransform.cpython-37.pyc deleted file mode 100644 index f100d5c..0000000 Binary files a/PIL/__pycache__/ImageTransform.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImageWin.cpython-37.pyc b/PIL/__pycache__/ImageWin.cpython-37.pyc deleted file mode 100644 index 091bd5e..0000000 Binary files a/PIL/__pycache__/ImageWin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/ImtImagePlugin.cpython-37.pyc b/PIL/__pycache__/ImtImagePlugin.cpython-37.pyc deleted file mode 100644 index 6ab9b86..0000000 Binary files a/PIL/__pycache__/ImtImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/IptcImagePlugin.cpython-37.pyc b/PIL/__pycache__/IptcImagePlugin.cpython-37.pyc deleted file mode 100644 index 024267e..0000000 Binary files a/PIL/__pycache__/IptcImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/Jpeg2KImagePlugin.cpython-37.pyc b/PIL/__pycache__/Jpeg2KImagePlugin.cpython-37.pyc deleted file mode 100644 index e155711..0000000 Binary files a/PIL/__pycache__/Jpeg2KImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/JpegImagePlugin.cpython-37.pyc b/PIL/__pycache__/JpegImagePlugin.cpython-37.pyc deleted file mode 100644 index 097528c..0000000 Binary files a/PIL/__pycache__/JpegImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/JpegPresets.cpython-37.pyc b/PIL/__pycache__/JpegPresets.cpython-37.pyc deleted file mode 100644 index 77085c8..0000000 Binary files a/PIL/__pycache__/JpegPresets.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/McIdasImagePlugin.cpython-37.pyc b/PIL/__pycache__/McIdasImagePlugin.cpython-37.pyc deleted file mode 100644 index cc70b67..0000000 Binary files a/PIL/__pycache__/McIdasImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/MicImagePlugin.cpython-37.pyc b/PIL/__pycache__/MicImagePlugin.cpython-37.pyc deleted file mode 100644 index 4702abd..0000000 Binary files a/PIL/__pycache__/MicImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/MpegImagePlugin.cpython-37.pyc b/PIL/__pycache__/MpegImagePlugin.cpython-37.pyc deleted file mode 100644 index 3e9c07b..0000000 Binary files a/PIL/__pycache__/MpegImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/MpoImagePlugin.cpython-37.pyc b/PIL/__pycache__/MpoImagePlugin.cpython-37.pyc deleted file mode 100644 index 5f6cad9..0000000 Binary files a/PIL/__pycache__/MpoImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/MspImagePlugin.cpython-37.pyc b/PIL/__pycache__/MspImagePlugin.cpython-37.pyc deleted file mode 100644 index 98786ce..0000000 Binary files a/PIL/__pycache__/MspImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PSDraw.cpython-37.pyc b/PIL/__pycache__/PSDraw.cpython-37.pyc deleted file mode 100644 index e50c3de..0000000 Binary files a/PIL/__pycache__/PSDraw.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PaletteFile.cpython-37.pyc b/PIL/__pycache__/PaletteFile.cpython-37.pyc deleted file mode 100644 index 0ed0f83..0000000 Binary files a/PIL/__pycache__/PaletteFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PalmImagePlugin.cpython-37.pyc b/PIL/__pycache__/PalmImagePlugin.cpython-37.pyc deleted file mode 100644 index db3cbb1..0000000 Binary files a/PIL/__pycache__/PalmImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PcdImagePlugin.cpython-37.pyc b/PIL/__pycache__/PcdImagePlugin.cpython-37.pyc deleted file mode 100644 index f341949..0000000 Binary files a/PIL/__pycache__/PcdImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PcfFontFile.cpython-37.pyc b/PIL/__pycache__/PcfFontFile.cpython-37.pyc deleted file mode 100644 index 3215896..0000000 Binary files a/PIL/__pycache__/PcfFontFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PcxImagePlugin.cpython-37.pyc b/PIL/__pycache__/PcxImagePlugin.cpython-37.pyc deleted file mode 100644 index 7d7cd3a..0000000 Binary files a/PIL/__pycache__/PcxImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PdfImagePlugin.cpython-37.pyc b/PIL/__pycache__/PdfImagePlugin.cpython-37.pyc deleted file mode 100644 index b6fe777..0000000 Binary files a/PIL/__pycache__/PdfImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PdfParser.cpython-37.pyc b/PIL/__pycache__/PdfParser.cpython-37.pyc deleted file mode 100644 index 14483a1..0000000 Binary files a/PIL/__pycache__/PdfParser.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PixarImagePlugin.cpython-37.pyc b/PIL/__pycache__/PixarImagePlugin.cpython-37.pyc deleted file mode 100644 index 643b37e..0000000 Binary files a/PIL/__pycache__/PixarImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PngImagePlugin.cpython-37.pyc b/PIL/__pycache__/PngImagePlugin.cpython-37.pyc deleted file mode 100644 index 1017706..0000000 Binary files a/PIL/__pycache__/PngImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PpmImagePlugin.cpython-37.pyc b/PIL/__pycache__/PpmImagePlugin.cpython-37.pyc deleted file mode 100644 index d9e792c..0000000 Binary files a/PIL/__pycache__/PpmImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PsdImagePlugin.cpython-37.pyc b/PIL/__pycache__/PsdImagePlugin.cpython-37.pyc deleted file mode 100644 index e5baff5..0000000 Binary files a/PIL/__pycache__/PsdImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/PyAccess.cpython-37.pyc b/PIL/__pycache__/PyAccess.cpython-37.pyc deleted file mode 100644 index 22c6397..0000000 Binary files a/PIL/__pycache__/PyAccess.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/SgiImagePlugin.cpython-37.pyc b/PIL/__pycache__/SgiImagePlugin.cpython-37.pyc deleted file mode 100644 index 3be1fb8..0000000 Binary files a/PIL/__pycache__/SgiImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/SpiderImagePlugin.cpython-37.pyc b/PIL/__pycache__/SpiderImagePlugin.cpython-37.pyc deleted file mode 100644 index acfdbdf..0000000 Binary files a/PIL/__pycache__/SpiderImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/SunImagePlugin.cpython-37.pyc b/PIL/__pycache__/SunImagePlugin.cpython-37.pyc deleted file mode 100644 index b04028a..0000000 Binary files a/PIL/__pycache__/SunImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/TarIO.cpython-37.pyc b/PIL/__pycache__/TarIO.cpython-37.pyc deleted file mode 100644 index ed6b6ca..0000000 Binary files a/PIL/__pycache__/TarIO.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/TgaImagePlugin.cpython-37.pyc b/PIL/__pycache__/TgaImagePlugin.cpython-37.pyc deleted file mode 100644 index 538d98a..0000000 Binary files a/PIL/__pycache__/TgaImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/TiffImagePlugin.cpython-37.pyc b/PIL/__pycache__/TiffImagePlugin.cpython-37.pyc deleted file mode 100644 index 955145b..0000000 Binary files a/PIL/__pycache__/TiffImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/TiffTags.cpython-37.pyc b/PIL/__pycache__/TiffTags.cpython-37.pyc deleted file mode 100644 index 0e61346..0000000 Binary files a/PIL/__pycache__/TiffTags.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/WalImageFile.cpython-37.pyc b/PIL/__pycache__/WalImageFile.cpython-37.pyc deleted file mode 100644 index f442b6e..0000000 Binary files a/PIL/__pycache__/WalImageFile.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/WebPImagePlugin.cpython-37.pyc b/PIL/__pycache__/WebPImagePlugin.cpython-37.pyc deleted file mode 100644 index 8306023..0000000 Binary files a/PIL/__pycache__/WebPImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/WmfImagePlugin.cpython-37.pyc b/PIL/__pycache__/WmfImagePlugin.cpython-37.pyc deleted file mode 100644 index 6378411..0000000 Binary files a/PIL/__pycache__/WmfImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/XVThumbImagePlugin.cpython-37.pyc b/PIL/__pycache__/XVThumbImagePlugin.cpython-37.pyc deleted file mode 100644 index 98a294b..0000000 Binary files a/PIL/__pycache__/XVThumbImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/XbmImagePlugin.cpython-37.pyc b/PIL/__pycache__/XbmImagePlugin.cpython-37.pyc deleted file mode 100644 index 8055fc5..0000000 Binary files a/PIL/__pycache__/XbmImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/XpmImagePlugin.cpython-37.pyc b/PIL/__pycache__/XpmImagePlugin.cpython-37.pyc deleted file mode 100644 index 70b6c46..0000000 Binary files a/PIL/__pycache__/XpmImagePlugin.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/__init__.cpython-37.pyc b/PIL/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index b0e68a0..0000000 Binary files a/PIL/__pycache__/__init__.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/__main__.cpython-37.pyc b/PIL/__pycache__/__main__.cpython-37.pyc deleted file mode 100644 index b6b0072..0000000 Binary files a/PIL/__pycache__/__main__.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/_binary.cpython-37.pyc b/PIL/__pycache__/_binary.cpython-37.pyc deleted file mode 100644 index 1aa6375..0000000 Binary files a/PIL/__pycache__/_binary.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/_tkinter_finder.cpython-37.pyc b/PIL/__pycache__/_tkinter_finder.cpython-37.pyc deleted file mode 100644 index 8168862..0000000 Binary files a/PIL/__pycache__/_tkinter_finder.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/_util.cpython-37.pyc b/PIL/__pycache__/_util.cpython-37.pyc deleted file mode 100644 index 5a803e4..0000000 Binary files a/PIL/__pycache__/_util.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/_version.cpython-37.pyc b/PIL/__pycache__/_version.cpython-37.pyc deleted file mode 100644 index 17224fa..0000000 Binary files a/PIL/__pycache__/_version.cpython-37.pyc and /dev/null differ diff --git a/PIL/__pycache__/aaaaaaaaaaaaa b/PIL/__pycache__/aaaaaaaaaaaaa deleted file mode 100644 index 8b13789..0000000 --- a/PIL/__pycache__/aaaaaaaaaaaaa +++ /dev/null @@ -1 +0,0 @@ - diff --git a/PIL/__pycache__/features.cpython-37.pyc b/PIL/__pycache__/features.cpython-37.pyc deleted file mode 100644 index 1852114..0000000 Binary files a/PIL/__pycache__/features.cpython-37.pyc and /dev/null differ diff --git a/PIL/a b/PIL/a deleted file mode 100644 index 8b13789..0000000 --- a/PIL/a +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..da53bb9 --- /dev/null +++ b/Pipfile @@ -0,0 +1,17 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] + +[dev-packages] +black = "*" +flake8 = "*" +"fake-bpy-module-2.83" = "*" + +[requires] +python_version = "3.8" + +[pipenv] +allow_prereleases = true diff --git a/README.md b/README.md index a1e7d25..d264ff1 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,68 @@ -ImagePaste -== +# ImagePaste A simple Blender addon to grab images from your clipboard and paste as a reference image in viewport or onto the image editor, or even copy images from blender to clipboard. Works with blender 2.80 and above. -Installation --- -* Download the latest release from [releases page on github](https://github.com/Yeetus3141/ImagePaste/releases/) -* Go to `Edit > Preferences > Addons > Install` and select the downloaded zip file. -* Set the directory for saving images to avoid errors. - -Usage --- -* **Ctrl+Shift+V** or `Object Mode > Add > Image > Paste From Clipboard` in Object Mode to paste as a reference image. -* **Ctrl+Shift+Alt+V** or `Object Mode > Add > Image > Paste From Clipboard as Plane` in Object Mode to paste image as a plane -* **Ctrl+Shift+V** or `Image Editor > Image > Paste From Clipboard` in the Image Editor to paste as image. -* **Ctrl+Shift+V** or `Node Editor > Context Menu (Right Click) > Paste Images From Clipboard` in the Node Editor to paste image(s) as Image Texture Node(s). -* **Ctrl+Shift+C** or `Image Editor > Image > Copy To Clipboard` in the Image Editor to copy active image to clipboard. -* It is recommended to save the blend file before using this add-on to prevent the misplacement of image files. - -Notes --- -* Running Blender as adminstrator might fix some errors. -* Works on Windows and Linux (X11 Clipboard) (by [@thanhph111](https://github.com/thanhph111)) , does not work on MacOS (not yet, atleast) -* A material must be created (if not exists already) before using 'Paste Image As Node' feature. - -Changelog --- -> **v1.0.0 (4th Jan, 21)** ->> * Initial release. -> -> **v1.1.0 (6th Jan, 21)** ->> * Improved error management. ->> * The images are now saved in the same folder as the .blend file, in a newly created subfolder. If the blend file is not saved, it uses the directory set in preferences or the default temp directory, which might raise permission error. This feature is toggleable via addon preferences. ->> * Improved the UI in preferences. -> -> **v1.2.0 (6th Feb, 21)** ->> * Paste image from clipboard directly as a plane onto the viewport `Ctrl+Shift+Alt+V`. ->> * Supports image(s) copied from file explorer in Windows. ->> * Multiple images can now be pasted at the same time if multiple images are copied from the file explorer (only for Windows). ->> * Fixed an issue where images where saved with the same name in the default direcotry even with different blender sessions and led to different images being loaded from what was pasted ->> * Added icons for the buttons -> -> **v1.3.0 (12th Mar, 21)** ->> * Image(s) can be pasted directly into the Node Editor as Image Texture Node(s), using `Node Editor > Context Menu (Right Click) > Paste Images From Clipboard` or `Ctrl+Shift+V` ->> * Images can now be copied to clipboard. In the `Image Editor > Image > Copy To Clipboard`, or `Ctrl+Shift+C`. These images are also saved along with other images in the set directory. -> -> **v1.3.1 (14th Mar, 21)** ->> * Fixed issue with the copy to clipboard feature where it didn't work as intended for certain cases. -> -> **v1.3.2 (16th Apr, 21)** ->> * Updated image naming scheme, now with timestamps, preventing overwriting of saved images. ->> * Merged seperate build versions of ImagePaste for Blender version below 2.93a and above into one. -> -> **v1.4.0 (10th June, 21)** ->> * Now Supports X11 Clipboard on Linux platform, all thanks to [@thanhph111](https://github.com/thanhph111) - - -Additional Info --- -For any questions, suggestions or bug reports, join [my discord server](https://discord.gg/G8ajxwQuYT) contact me via twitter **@YeetusBlenditus** or e-mail me at **binitnew@gmail.com** + +## Installation + +1. Download the latest release from [releases page](https://github.com/Yeetus3141/ImagePaste/releases/) (you can view the changelog [here](CHANGELOG.md)). +1. Go to `Edit > Preferences > Addons > Install` and select the downloaded zip file, then tick the box beside the add-on name. +1. Set the directory for saving images to avoid errors. + + +## Usage + +- `Ctrl + Shift + V` or `Object Mode > Add > Image > Paste From Clipboard` in Object Mode to paste as a reference image. +- `Ctrl + Shift + Alt + V` or `Object Mode > Add > Image > Paste From Clipboard as Plane` in Object Mode to paste image as a plane. +- `Ctrl + Shift + V` or `Image Editor > Image > Paste From Clipboard` in the Image Editor to paste as image. +- `Ctrl + Shift + V` or `Node Editor > Context Menu (Right Click) > Paste Images From Clipboard` in the Node Editor to paste image(s) as Image Texture Node(s). +- `Ctrl + Shift + C` or `Image Editor > Image > Copy To Clipboard` in the Image Editor to copy active image to clipboard. +- It is recommended to save the blend file before using this add-on to prevent the misplacement of image files. + +![demo](assets/demo.gif) + + +## Notes + +- Running Blender as administrator might fix some errors. +- Works on Windows and Linux (X11 server) (by [@thanhph111](https://github.com/thanhph111)), does not work on MacOS (not yet, at least). +- A material must be created (if not exists already) before using **Paste Image As Node** feature. + + +## Setup environment for development + +[Recommended style guide for Blender add-ons](https://wiki.blender.org/wiki/Style_Guide/Python) is followed by this repository with these tool: +- Linter: **Flake8** (latest, configured in [.flake8](.flake8)). +- Formatter: **Black** (latest, default settings). +- Environment manager: **pipenv** (configured in [Pipfile](Pipfile)). + +These steps will show how to set up a python virtual environment that fits my workflow. +1. Open CLI in the project directory. +1. Run following command `pipenv install --dev` to install packages for development. +1. After that, a virtual environment has been setup. You can get in using `pipenv shell` and get out with `exit`. Once activated, you will have all packages you need. + +Some editor configurations are also defined in [.editorconfig](.editorconfig). + +I am personally using Visual Studio Code as editor. If you also use it, you should have these workspace settings: + +```json +{ + // Python language configuration + "[python]": { + "editor.rulers": [88], + "editor.wordWrap": "wordWrapColumn", + "editor.wordWrapColumn": 88 + }, + // Overwrite flake8 user settings (if any) to be accepted in .flake8 + "python.linting.flake8Args": [], + // Set default Python formatter and reset it to default settings + "python.formatting.provider": "black", + "python.formatting.blackArgs": [] +} +``` + + +## Additional Info + +For any questions, suggestions or bug reports, join [my discord server](https://discord.gg/G8ajxwQuYT) contact me via twitter **@YeetusBlenditus** or e-mail me at **binitnew@gmail.com**. diff --git a/__init__.py b/__init__.py index e2ac4a6..bc586a4 100644 --- a/__init__.py +++ b/__init__.py @@ -1,88 +1,86 @@ -#ImagePaste addon for Blender 2.80+ to paste image from your clipboard into your blender workflow -#Managed by: Binit (aka Yeetus) - - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -bl_info = { - "name" : "ImagePaste", - "author" : "Binit", - "description" : "Paste image from you clipboard as a Reference or into the Image Editor", - "blender" : (2, 80, 0), - "version" : (1, 4, 0), - "location" : "Object Mode > Toolbar > Add > Image, Image Editor > Toolbar > Image, Node Editor > Context Menu", - "warning" : "", - "category" : "Import-Export" -} - - import os import platform + import bpy -from bpy.types import Operator, AddonPreferences -from bpy.props import StringProperty, BoolProperty import addon_utils +from bpy.props import StringProperty, BoolProperty +from bpy.types import Operator, AddonPreferences + + +bl_info = { + "name": "ImagePaste", + "author": "Binit", + "description": ( + "Paste image from you clipboard as a Reference or into the Image Editor" + ), + "blender": (2, 80, 0), + "version": (1, 4, 0), + "location": ( + "View3D > Add > Image, " + "Image Editor > Toolbar > Image, " + "Node Editor > Context Menu" + ), + "warning": "", + "category": "Import-Export", +} +# Platform router if platform.system() == "Windows": from .windows import GrabImage, CopyImage elif platform.system() == "Linux": from .linux import GrabImage, CopyImage else: - raise("Unsupported current platform") + raise Exception("Unsupported current platform") -addon_utils.enable("io_import_images_as_planes") #enable the "Import Images as Planes" addon to be used here +# Enable the "Import Images as Planes" addon to be used here +addon_utils.enable("io_import_images_as_planes") class ImagePastePreferences(AddonPreferences): bl_idname = __name__ default_img_dir: StringProperty( - name= "Default directory", - subtype= 'DIR_PATH', - default= bpy.context.preferences.filepaths.temporary_directory, - ) + name="Default directory", + subtype="DIR_PATH", + default=bpy.context.preferences.filepaths.temporary_directory, + ) force_default_dir: BoolProperty( - name= "Always use default directory", + name="Always use default directory", default=False, - ) + ) def draw(self, context): layout = self.layout - layout.label(text="Default directory for saving image files. This directory will be used if") - layout.label(text="The blend file is not saved, or Always use default directory' is checked.") + layout.label(text="Default directory for saving image files.") + layout.label( + text=( + "This directory will be used if" + "the blend file is not saved, " + "or always use default directory if it is checked." + ) + ) layout.prop(self, "default_img_dir") layout.prop(self, "force_default_dir") class PasteImageToImageEditor(Operator): """Paste image from clipboard into the Image Editor""" - bl_idname = "imgpaste.paste_ie" - bl_label = "Paste From Clipboard" + bl_idname = "impaste.paste_ie" + bl_label = "Paste From Clipboard" def execute(self, context): img_data = GrabImage() if img_data == 0: - self.report({'ERROR'}, 'No image data on clipboard') - return {'CANCELLED'} + self.report({"ERROR"}, "No image data on clipboard") + return {"CANCELLED"} elif img_data == 1: - self.report({'ERROR'}, 'Unable to save image') - return {'CANCELLED'} + self.report({"ERROR"}, "Unable to save image") + return {"CANCELLED"} else: img_dir, img_name = img_data @@ -91,16 +89,17 @@ def execute(self, context): current_img = bpy.data.images[img_name[-1]] - #set current image as active in image editor - for area in bpy.context.screen.areas : - if area.type == 'IMAGE_EDITOR' : + # Set current image as active in image editor + for area in bpy.context.screen.areas: + if area.type == "IMAGE_EDITOR": area.spaces.active.image = current_img - return {'FINISHED'} + return {"FINISHED"} class PasteImageToReference(Operator): """Load reference image from clipboard""" + bl_idname = "impaste.paste_ref" bl_label = "Paste From Clipboard" @@ -108,22 +107,23 @@ def execute(self, context): img_data = GrabImage() if img_data == 0: - self.report({'ERROR'}, 'No image data on clipboard') - return {'CANCELLED'} + self.report({"ERROR"}, "No image data on clipboard") + return {"CANCELLED"} elif img_data == 1: - self.report({'ERROR'}, 'Unable to save image') - return {'CANCELLED'} + self.report({"ERROR"}, "Unable to save image") + return {"CANCELLED"} else: img_dir, img_name = img_data for directory in img_dir: bpy.ops.object.load_reference_image(filepath=directory) - return {'FINISHED'} + return {"FINISHED"} class PasteImageAsPlane(Operator): """Load image from clipboard as a plane""" + bl_idname = "impaste.paste_as_plane" bl_label = "Paste From Clipboard as Plane" @@ -131,26 +131,28 @@ def execute(self, context): img_data = GrabImage() if img_data == 0: - self.report({'ERROR'}, 'No image data on clipboard') - return {'CANCELLED'} + self.report({"ERROR"}, "No image data on clipboard") + return {"CANCELLED"} elif img_data == 1: - self.report({'ERROR'}, 'Unable to save image') - return {'CANCELLED'} + self.report({"ERROR"}, "Unable to save image") + return {"CANCELLED"} else: img_dir, img_name = img_data - for directory in img_dir: name = os.path.basename(directory) path = os.path.dirname(directory) - bpy.ops.import_image.to_plane(files=[{"name":name, "name":name}], directory=path, relative = False) + bpy.ops.import_image.to_plane( + files=[{"name": name, "name": name}], directory=path, relative=False + ) - return {'FINISHED'} + return {"FINISHED"} class PasteImageToNodeEditor(Operator): """Paste image(s) from clipboard as image texture node(s)""" + bl_idname = "impaste.paste_as_node" bl_label = "Paste Images From Clipboard" @@ -158,14 +160,13 @@ def execute(self, context): img_data = GrabImage() if img_data == 0: - self.report({'ERROR'}, 'No image data on clipboard') - return {'CANCELLED'} + self.report({"ERROR"}, "No image data on clipboard") + return {"CANCELLED"} elif img_data == 1: - self.report({'ERROR'}, 'Unable to save image') - return {'CANCELLED'} + self.report({"ERROR"}, "Unable to save image") + return {"CANCELLED"} else: - img_dir, img_name = img_data - + img_dir, _ = img_data tree = context.space_data.edit_tree locX, locY = context.space_data.cursor_location @@ -173,122 +174,183 @@ def execute(self, context): for directory in img_dir: node = tree.nodes.new("ShaderNodeTexImage") node.location = locX, locY - locY += 250 # offset location for next node + # Offset location for next node + locY += 250 - node_img = bpy.data.images.load(filepath = directory) + node_img = bpy.data.images.load(filepath=directory) node.image = node_img - return {'FINISHED'} + return {"FINISHED"} class CopyImageToClipboard(Operator): """Copy image to clipboard""" + bl_idname = "impaste.copy_img" bl_label = "Copy To Clipboard" def execute(self, context): for area in context.screen.areas: - if area.type == 'IMAGE_EDITOR': + if area.type == "IMAGE_EDITOR": active_img = area.spaces.active.image if active_img.filepath: CopyImage(active_img.filepath) else: - if bpy.data.filepath and bpy.context.preferences.addons[__name__].preferences.force_default_dir == False: - # save image in the place where the blendfile is saved, in a newly created subfolder (if saved and force_default_directory is set to false) - Directory = os.path.join(os.path.split(bpy.data.filepath)[0], 'ImagePaste') - - if os.path.isdir(Directory) == False: + if ( + bpy.data.filepath + and not bpy.context.preferences.addons[ + __name__ + ].preferences.force_default_dir + ): + # If saved and force_default_directory is set to false + # save image in the place where the .blend file is saved + # in a newly created subfolder + Directory = os.path.join( + os.path.split(bpy.data.filepath)[0], "ImagePaste" + ) + + if not os.path.isdir(Directory): os.mkdir(Directory) else: - # just use the default location otherwise - Directory = bpy.context.preferences.addons[__name__].preferences.default_img_dir + # Just use the default location otherwise + Directory = bpy.context.preferences.addons[ + __name__ + ].preferences.default_img_dir - img_dir = os.path.join(Directory, active_img.name + '.png') - bpy.ops.image.save_as(save_as_render=True, copy=True, filepath = img_dir) + img_dir = os.path.join(Directory, active_img.name + ".png") + bpy.ops.image.save_as(save_as_render=True, copy=True, filepath=img_dir) CopyImage(img_dir) - return {'FINISHED'} + return {"FINISHED"} -# menu functions +# Menu functions def menu_func_ie(self, context): self.layout.operator(PasteImageToImageEditor.bl_idname, icon="FILE_IMAGE") + + def menu_func_ref(self, context): self.layout.operator(PasteImageToReference.bl_idname, icon="FILE_IMAGE") -def menu_func_asplane(self, context): + + +def menu_func_as_plane(self, context): self.layout.operator(PasteImageAsPlane.bl_idname, icon="IMAGE_PLANE") -def menu_func_asnode(self, context): + + +def menu_func_as_node(self, context): self.layout.operator(PasteImageToNodeEditor.bl_idname, icon="FILE_IMAGE") -def menu_func_toclipboard(self, context): + + +def menu_func_to_clipboard(self, context): self.layout.operator(CopyImageToClipboard.bl_idname, icon="COPYDOWN") -# list of all classes for registeration/unregistration -classes = (PasteImageToReference, PasteImageAsPlane, PasteImageToImageEditor, ImagePastePreferences, PasteImageToNodeEditor, CopyImageToClipboard) +# List of all classes to register/unregister +classes = ( + PasteImageToReference, + PasteImageAsPlane, + PasteImageToImageEditor, + ImagePastePreferences, + PasteImageToNodeEditor, + CopyImageToClipboard, +) -# store keymaps here to access after registration +# Store keymaps here to access after registration addon_keymaps = [] +kc = None def register(): - # register classes + # Register classes for current in classes: bpy.utils.register_class(current) - # register menus + # Register menus bpy.types.IMAGE_MT_image.append(menu_func_ie) bpy.types.VIEW3D_MT_image_add.append(menu_func_ref) - bpy.types.VIEW3D_MT_image_add.append(menu_func_asplane) - bpy.types.NODE_MT_context_menu.append(menu_func_asnode) - bpy.types.IMAGE_MT_image.append(menu_func_toclipboard) + bpy.types.VIEW3D_MT_image_add.append(menu_func_as_plane) + bpy.types.NODE_MT_context_menu.append(menu_func_as_node) + bpy.types.IMAGE_MT_image.append(menu_func_to_clipboard) - # register keymaps + # Register keymaps wm = bpy.context.window_manager kc = wm.keyconfigs.addon if kc: - km = kc.keymaps.new(name='Image Generic',space_type='IMAGE_EDITOR') - kmi = km.keymap_items.new(PasteImageToImageEditor.bl_idname,type='V',value='PRESS',ctrl=True,shift=True) - addon_keymaps.append((km,kmi)) - - km = kc.keymaps.new(name='3D View',space_type='VIEW_3D') - kmi = km.keymap_items.new(PasteImageToReference.bl_idname,type='V',value='PRESS',ctrl=True,shift=True) - addon_keymaps.append((km,kmi)) - - km = kc.keymaps.new(name='3D View',space_type='VIEW_3D') - kmi = km.keymap_items.new(PasteImageAsPlane.bl_idname, type='V',value='PRESS',ctrl=True,shift=True,alt=True) - addon_keymaps.append((km,kmi)) - - km = kc.keymaps.new(name='Node Editor',space_type='NODE_EDITOR') - kmi = km.keymap_items.new(PasteImageToNodeEditor.bl_idname, type='V',value='PRESS',ctrl=True,shift=True) - addon_keymaps.append((km,kmi)) - - km = kc.keymaps.new(name='Image Generic',space_type='IMAGE_EDITOR') - kmi = km.keymap_items.new(CopyImageToClipboard.bl_idname, type='C',value='PRESS',ctrl=True,shift=True) - addon_keymaps.append((km,kmi)) + km = kc.keymaps.new(name="Image Generic", space_type="IMAGE_EDITOR") + kmi = km.keymap_items.new( + PasteImageToImageEditor.bl_idname, + type="V", + value="PRESS", + ctrl=True, + shift=True, + ) + addon_keymaps.append((km, kmi)) + + km = kc.keymaps.new(name="3D View", space_type="VIEW_3D") + kmi = km.keymap_items.new( + PasteImageToReference.bl_idname, + type="V", + value="PRESS", + ctrl=True, + shift=True, + ) + addon_keymaps.append((km, kmi)) + + km = kc.keymaps.new(name="3D View", space_type="VIEW_3D") + kmi = km.keymap_items.new( + PasteImageAsPlane.bl_idname, + type="V", + value="PRESS", + ctrl=True, + shift=True, + alt=True, + ) + addon_keymaps.append((km, kmi)) + + km = kc.keymaps.new(name="Node Editor", space_type="NODE_EDITOR") + kmi = km.keymap_items.new( + PasteImageToNodeEditor.bl_idname, + type="V", + value="PRESS", + ctrl=True, + shift=True, + ) + addon_keymaps.append((km, kmi)) + + km = kc.keymaps.new(name="Image Generic", space_type="IMAGE_EDITOR") + kmi = km.keymap_items.new( + CopyImageToClipboard.bl_idname, + type="C", + value="PRESS", + ctrl=True, + shift=True, + ) + addon_keymaps.append((km, kmi)) def unregister(): - - # unregister classes + # Unregister classes for current in classes: bpy.utils.unregister_class(current) - # unregister menus + # Unregister menus bpy.types.IMAGE_MT_image.remove(menu_func_ie) bpy.types.VIEW3D_MT_image_add.remove(menu_func_ref) - bpy.types.VIEW3D_MT_image_add.remove(menu_func_asplane) - bpy.types.NODE_MT_context_menu.remove(menu_func_asnode) - bpy.types.IMAGE_MT_image.remove(menu_func_toclipboard) - - # unregister keymaps - for km,kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() + bpy.types.VIEW3D_MT_image_add.remove(menu_func_as_plane) + bpy.types.NODE_MT_context_menu.remove(menu_func_as_node) + bpy.types.IMAGE_MT_image.remove(menu_func_to_clipboard) + + # Unregister keymaps + if kc: + for km, kmi in addon_keymaps: + km.keymap_items.remove(kmi) + addon_keymaps.clear() + if __name__ == "__main__": register() diff --git a/assets/demo.gif b/assets/demo.gif new file mode 100644 index 0000000..3fb307f Binary files /dev/null and b/assets/demo.gif differ diff --git a/linux.py b/linux.py index af100c2..00a55f4 100644 --- a/linux.py +++ b/linux.py @@ -53,7 +53,7 @@ def GrabImage(): return paths, [os.path.basename(path) for path in paths] -# function to copy image from given path to clipboard +# Function to copy image from given path to clipboard def CopyImage(img_path): script_file = os.path.realpath(__file__) directory = os.path.dirname(script_file) diff --git a/windows.py b/windows.py index 31acdb4..0cc6313 100644 --- a/windows.py +++ b/windows.py @@ -7,16 +7,16 @@ try: from .win32_py37 import win32clipboard -except: +except Exception: from .win32_py39 import win32clipboard -# function to grab image(s) from clipboard, save them and return their names and paths +# Function to grab image(s) from clipboard, save them and return their names and paths def GrabImage(): img = ImageGrab.grabclipboard() - if img == None: + if img is None: return 0 if type(img) == list: @@ -24,37 +24,46 @@ def GrabImage(): img_name = [os.path.basename(current) for current in img_dir] return img_dir, img_name - #generate the name of the image with timestamp to prevent overwriting + # Generate the name of the image with timestamp to prevent overwriting timestamp = time.strftime("%y%m%d-%H%M%S") - img_name = 'PastedImage' + timestamp + '.png' - - if bpy.data.filepath and bpy.context.preferences.addons[__package__].preferences.force_default_dir == False: - # save image in the place where the blendfile is saved, in a newly created subfolder (if saved and force_default_directory is set to false) - Directory = os.path.join(os.path.split(bpy.data.filepath)[0], 'ImagePaste') - - if os.path.isdir(Directory) == False: + img_name = "PastedImage" + timestamp + ".png" + + if ( + bpy.data.filepath + and not bpy.context.preferences.addons[ + __package__ + ].preferences.force_default_dir + ): + # If saved and force_default_directory is set to false + # save image in the place where the .blend file is saved + # in a newly created subfolder + Directory = os.path.join(os.path.split(bpy.data.filepath)[0], "ImagePaste") + + if not os.path.isdir(Directory): os.mkdir(Directory) else: - # just use the default location otherwise - Directory = bpy.context.preferences.addons[__package__].preferences.default_img_dir + # Just use the default location otherwise + Directory = bpy.context.preferences.addons[ + __package__ + ].preferences.default_img_dir - img_dir = Directory + '\\' + img_name + img_dir = Directory + "\\" + img_name try: img.save(img_dir) - except: + except Exception: return 1 return [img_dir], [img_name] -# function to copy image from given path to clipboard +# Function to copy image from given path to clipboard def CopyImage(img_path): image = Image.open(img_path) img_out = BytesIO() - image.convert('RGB').save(img_out, 'BMP') + image.convert("RGB").save(img_out, "BMP") data = img_out.getvalue()[14:] img_out.close()