Code Monkey home page Code Monkey logo

yoga's Introduction

YOGA - Yummy Optimizer for Gorgeous Assets

Github Discord PYPI Version Build Status Black License

YOGA is a command-line tool and a library that can:

  • convert and optimize images from various format to JPEG, PNG and WEBP,
  • convert and optimize 3D models from various formats to glTF and GLB.

Images are opened using Pillow and optimized using Guetzli and MozJPEG for JPEGs, Zopflipng for PNGs and libwebp for WEBPs.

3D Models are converted and optimized using assimp. If models contain or reference images, they are processed by YOGA's image optimizer.

EXAMPLE: Converting and optimizing an image from CLI:

yoga  image  input.png  output.png
yoga  image  --output-format=jpeg  --jpeg-quality=84  input.png  output.jpg
yoga  image  --help

EXAMPLE: Converting and optimizing a 3D model from CLI:

yoga  model  input.fbx  output.glb
yoga  model  --no-graph-optimization  --no-meshes-optimization  --image-output-format=jpeg  --image-jpeg-quality=84  input.fbx  output.glb
yoga  model  --help

Install

Documentation

Changelog

  • [NEXT] (changes on master that have not been released yet):
    • Nothing yet ;)
  • v1.3.1-1:
    • This version has no code change from the v1.3.1. It is only an update of the distribution :
      • A brand new standalone version was build for Linux
      • The Windows standalone distribution was updated (changes in documentation)
    • dist: Added scripts to build a standalone binary version of YOGA on Linux
  • v1.3.1:
    • chore(sdist): Fixed included files in sdist package (@flozz)
  • v1.3.0:
    • feat(assimp): Updated assimp to v5.3.1 (fixed build on GCC >= 13) (@flozz)
    • chore: Removed a script that is no more needed (@flozz)
    • docs: Updated contributing documentation (libraries, supported Python version, assimp update) (@flozz)
  • v1.2.3:
    • Code quality: more robust type comparison (@flozz)
    • Code quality: cleanup some Python 2.7 specific code (@flozz)
    • Added Python 3.12 support (@flozz)
    • Removed Python 3.7 support (@flozz)
  • v1.2.2:
    • Updated the code to not use deprecated constants on newer Pillow versions
    • Various typo fixed (@kianmeng, #45)
    • Added Python 3.11 support
  • v1.2.1:
    • No change: fix an upload error on PYPI
  • v1.2.0:
    • Add color quantization options (based on libimagequant)
    • arm64 and universal2 wheels for macOS
    • x86 and x68_64 wheels for musl-based Linux distro (Alpine,...)
    • MAINTAINERS: New dependency: imagequant
  • v1.1.2:
    • Add flag to CFFI builder to fix MacOS build
  • v1.1.1 (not published):
    • JPEG: ignore invalid values for the orientation tag (#38)
    • Python 3.10 support and wheels
  • v1.1.0:
    • JPEG Optimization:
      • Honor the JPEG orientation EXIF tag
      • JPEG optimization has been improved by using some optimizations from MozJPEG after the Guetzli encoding (from 2.4 % to 7.3 % of additional size reduction)
    • PNG Optimization:
      • YOGA can no more output a PNG larger than the input one when performing a PNG to PNG optimization
    • CLI:
      • Allow to cancel an optimization using Ctrl+C (NOTE: may not work on Windows)
      • Add a --version option to get YOGA's version
      • Improve yoga --help usage
    • Python versions:
      • Python 2.7 support dropped
    • NOTE for packagers:
  • v1.0.0:
    • WEBP (lossy and lossless) images supported as output format
    • PNG default optimization preset changed to a 10× faster preset (old preset still available with --png-slow-optimization flag)
    • New model flag --no-fix-infacing-normals to disable Assimp's "fix infacing normals" postprocess (#32, #33)
    • Show CLI usage when no parameter given
    • Developer documentation improved (#31)
    • ASSIMP library updated
    • WARNING: This is the last version to actively support Python 2.7!
  • v0.11.1:
    • Automated workflow for deploying the PyPI packages
    • Wheel are now distributed on PyPI
  • v0.11.0:
    • Allows to build YOGA on Windows
    • Scripts and workflow to build Windows standalone versions
  • v0.10.2:
    • Updates assimp and python libraries
  • v0.10.1:
    • Fixes an issue that occurs when output file does not already exist
  • v0.10.0:
    • Prevent overwriting of the output file when an error occurs (#17)
    • Unicode path support (#16)
  • v0.10.0b1:
    • Verbose and quiet modes,
    • Allows to pass textures from memory instead of looking on the filesystem,
    • Allows to pass a fallback texture instead of raising an error.
  • v0.9.1b1:
    • Automatic selection of the output format (png or jpeg),
    • Prevent duplication of textures that are shared between materials,
    • Fixes Windows paths of textures.
  • v0.9.0b1: First release (only GLB output for models, no image auto output format)

yoga's People

Contributors

damienfern avatar dependabot[bot] avatar flozz avatar kianmeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yoga's Issues

Add option to keep only the meshes

Some files like FBX support lights and cameras, but these are not always useful.

Assimp supports an importer post-process called aiProcess_RemoveComponent and configured with:

importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_CAMERAS | aiComponent_LIGHTS);

We might want yoga to remove everything but meshes/materials by default, and provide a --no-cleanup option in the CLI and such.

Option to keep metadata

Someone requested an option to keep metadata, so I open this issue to keep the information.

Questions that should be answered before:

  • How to achieve this for each formats?
  • What to do when the input format is different than the output format (converting metadata? What can be kept ?)...

[Feature request] progression indicator

Hello,

Because of the very long computation time for a lot of images (#28), a progression indicator (like a progress bar, or just a vague percentage) would be useful to estimate how long the processing will take.
What do you think about such a feature ? Any chance it gets implemented ?

Thank you

Inverted normals on a specific model

I used yoga to convert a fbx (composed of two submeshes) into a glb and the normals of one of submesh are inverted.

There is a screen:
screen

I set Blender in display normals mode. Blue color is normals facing the camera

Error when executed by user that didn't compiledthepackage on ArchLinux

How the ArchLinux package is compiled: Depend on assimp, because unable to install it following instruction. The assimp source code is still needed to compile yoga. So

  • get assimp-5.0.1.tar.gz
  • remove assimp/build
  • untar assimp and add link at the same place
    python3 setup.py build_py

build_py is the only one that don't make error, and need this lib. The other documented build process don't work on Arch.
The files are then placed in the package dir using:
python setup.py install --root="${pkgdir}" --optimize=1 --skip-build

After installing the made package, it works fine with the user that build the package, but with other user, there is strangely the following error. could be due to some parts that are installed only for the compiling user during the build process?

Traceback (most recent call last):
  File "/usr/bin/yoga", line 33, in <module>
    sys.exit(load_entry_point('yoga==1.0.0', 'console_scripts', 'yoga')())
  File "/usr/bin/yoga", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/lib/python3.9/importlib/metadata.py", line 77, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 855, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/usr/lib/python3.9/site-packages/yoga/__init__.py", line 2, in <module>
    from . import model  # noqa
  File "/usr/lib/python3.9/site-packages/yoga/model/__init__.py", line 174, in <module>
    from .assimp import assimp_import_from_bytes, assimp_export_to_bytes
  File "/usr/lib/python3.9/site-packages/yoga/model/assimp.py", line 6, in <module>
    from ._assimp import lib, ffi
ModuleNotFoundError: No module named 'yoga.model._assimp'

Cannot resolve normalized_image_path

Expected Behavior

When trying to optimize a glb file, application should return an optimized glb file.

Current Behavior

When trying to optimize a glb file, application returns ValueError: Cannot resolve *13 and quits

Steps to Reproduce

  1. Using latest Windows version - yoga 1.3.1
  2. Using latest Windows version of Blender - blender 4.0.2
  3. Using Blender glb/gltf exporter, export 3D model
  4. Using Yoga, run yoga model input.glb output.glb

Context (Environment)

  • OS: Win 11
  • Blender: 4.0.2
  • Yoga: 1.3.1 / 1.3.0

Detailed Error Log

Traceback (most recent call last):
  File "C:\yoga\yogawin.py", line 6, in <module>
  File "C:\yoga\yoga\__main__.py", line 25, in main
  File "C:\yoga\concurrent\futures\_base.py", line 449, in result
  File "C:\yoga\concurrent\futures\_base.py", line 401, in __get_result
  File "C:\yoga\concurrent\futures\thread.py", line 58, in run
  File "C:\yoga\yoga\model\__init__.py", line 251, in optimize
  File "C:\yoga\yoga\model\helpers.py", line 135, in model_embed_images
ValueError: Cannot resolve *13

Possible solution

Maybe is something related to the blender exported file?

Keep metadata when optimizing same format

Summary

As a user I want to be able to keep Exif/XMP/IPTC or other metadata when optimizing an image, so that metadata affecting image rendering are kept.

Why

As we've discussed on discord I've found that when optimizing a file, yoga strip it from metadata. It result in a change of color of resulting image, weither when optimizing to webp or jpg.

Example file

Below are source file in JPG, and webp image in a zip (github is not compatible with webp upload)
img_webp.zip

img_brute_photoshop.jpg

Raw image from a photoshop export, lot of EXIF metadata
img_brute_photoshop

img_export_gimp_no_exif.webp

Converted image using Gimp, there is still metadata as seen with this extract:

+-- img_export_gimp_no_exif.webp
    +-- RIFF [size: 16697518, formtype: WEBP]
        +-- VP8X [offset: 20, size: 10]
            +-- has_icc: 1
            +-- has_alpha: 0
            +-- has_exif: 1
            +-- has_xmp: 0
            +-- has_anim: 0
            +-- canvas_width: 4252
            +-- canvas_height: 2835
        +-- ICCP [offset: 38, size: 532]
        +-- VP8L [offset: 578, size: 16696926]
        +-- EXIF [offset: 16697512, size: 14]

img_optimized_noresized.webp

Optimised image without resizing, with a loss of color, no metadata.

img_optimized_resized.webp

Optimised image with resizing, same loss of color, no metadata.

Add Windows compatibility

The documentation says:

Building YOGA on Windows is not supported yet...

It could be nice to be able to use YOGA also on Windows!

Multithreading support ?

Hello,
Any chance that Yoga includes multi-threading in the future ?

Overall performance seems pretty ok for small jpeg images, but for bigger ones it's really slow. One 75MB PNG (50Mpixels) took 30min to be converted, a 1.6MB PNG took 6min (but 33% saved, nice :).

Thanks

High memory usage during image conversion

Hello,

I did convert a few files and notices a very high memory usage (often about 12 times the size of the original png), and in particular my last test with a 9000x3000 PNG file (44MB) did use more than 20GB of RAM, which seems extreme for such a file…
So I wonder if that's something expected (and if yes, what would be possible to reduce the memory usage ?) or a bug on my side.

Thanks in advance

Grayscale encoding mode

This is a bit of a corner case, but it is useful for massively shrinking size further when dealing with scanned documents, especially text or some types of drawings: the ability to force the image to be in grayscale instead of RGB color. Oftentimes, document scanning apps (or people who do the scanning) may not think (or know) to encode that way, so the image is imperceptibly color even though perceptually it is grayscale. Converting to grayscale, for PNG and other lossless (or lossy) formats helps a ton... but doing it one image at a time with GIMP is a pain in the butt.

The same rule applies to alpha channels: sometimes there is one even if you don't necessarily need it, and it's extra weight that could be discarded (if the user knows what they're doing :)

GUI planned ?

Hello,

I would like to know if you are planning to implement a Graphical User Interface for that software ?

Thanks

Optimize outputted meshes with meshoptimizer

Looking at zeux/meshoptimizer, we could use some optimization to assimp output geometries.

First do some tests with outputted geometries by YOGA, count the gains, and see if an integration as a lib is doable.

TODO-list:

  • Test gltf optimizer with multiple geometries, measure the gains if any
  • See if it is usable as a library to add to YOGA (python bindings)
  • Write python bindings
  • Integrate to YOGA (and option to deactivate those optimizations ?)

Cannot open /var/www

Just installed Yoga and I cannot browse /var/www to open files in my local web dev directories. Is there a way for me to let Yoga see these directories? I have tried via 'Other locations' with no success.

Optimize already embedded textures

In yoga/model/assimp.cpp, extract_image_nodes does not extract already embedded textures, they are ignored.

Keeping the very same convention than assimp, we could just fill imageNode with:

auto imageNode = new ImageNode();
imageNode->path = "*1"; // Same convention, the 1 is the index of the textures in scene->mTextures
imageNode->bytes = /* extract bytes for scene->mTextures */;
imageNode->bytes_length = /* extract bytes length */;

Allow to do a lossless jpeg to jpeg optimization using mozjpeg only

Add choices for JPEG optimization:

  • Guetzli + MozJPEG

    • Always reencode JPEGs using Guetzli and then use additional MozJPEG (lossless) optimization
  • MozJPEG

    • Always reencode JPEGs using libjpeg and then optimize losslessly with MozJPEG
  • MozJPEG lossless

    • If the input image is already a JPEG: only perform a lossless optimization using MozJPEG (ignore the quality parameter)
    • If the input image is not a JPEG: encode the image using libjpeg (Pillow) and then optimize it with MozJPEG (lossless)

Related issue: flozz/yoga-image-optimizer#15

JPEG → JPEG optimization: keep the original image if the output image is bigger than the input one

When doing a JPEG to JPEG optimization, we should never have an output image bigger than the input one.

  • If the guetzli+mozjpeg reencoding produce a smaller image → keep it
  • else, try a mozjpeg (lossless) optimization alone, and if it produces a smaller image → keep this one
  • else, just remove metadata and keep the original encoding.

Issue #43 must be resolved before this one

Related issue: flozz/yoga-image-optimizer#14

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.