Convert JPG or PNG to Webp with Python



To convert images to the WEBP format using Python, you can use the Pillow library, which provides an easy-to-use interface for image processing. Make sure you have Pillow installed before proceeding.

Here's an example code snippet that demonstrates how to convert an image file to WEBP


```python

from PIL import Image


def convert_to_webp(image_path, output_path):

image = Image.open(image_path)

image.save(output_path, "WEBP")


# Example usage

input_image_path = "input.jpg"

output_image_path = "output.webp"

convert_to_webp(input_image_path, output_image_path)

```


In this example, the `convert_to_webp` function takes two parameters: `image_path` specifies the path to the input image file (e.g., `"input.jpg"`), and `output_path` specifies the path where the converted WEBP image will be saved (e.g., `"output.webp"`). The function uses `Image.open()` to open the input image, and then `image.save()` with `"WEBP"` as the format to save the converted image as WEBP.


You can replace `"input.jpg"` and `"output.webp"` with your desired input and output image paths. Make sure the input image file exists and has the correct format, and the output path is writable.

Another example could look like this. 
The biggest difference is during save parameter format is passed and filesystem glob makes collating a bit easier. But in fact I'd like to save it in an adjacent folder.





Then we need to To resize an image in Python while maintaining a minimum size constraint. Here's an updated version that allows resizing the image by a percentage while ensuring it doesn't become smaller than a specified minimum size:

```python
from PIL import Image

def resize_image_with_min_size(input_image_path, output_image_path, percentage, min_width, min_height):
    image = Image.open(input_image_path)
    width, height = image.size

    # Calculate the target size based on the percentage
    new_width = int(width * percentage)
    new_height = int(height * percentage)

    # Check if the new size is smaller than the minimum size
    new_width = max(new_width, min_width)
    new_height = max(new_height, min_height)

    # Resize the image
    resized_image = image.resize((new_width, new_height))
    resized_image.save(output_image_path)

# Example usage
input_image_path = "input.jpg"
output_image_path = "output.jpg"
percentage = 0.75
min_width = 800
min_height = 600
resize_image_with_min_size(input_image_path, output_image_path, percentage, min_width, min_height)
```

In this updated code, the `resize_image_with_min_size` function takes five parameters: `input_image_path` specifies the path to the input image file, `output_image_path` specifies the path where the resized image will be saved, `percentage` specifies the resize percentage (e.g., `0.75` for 75% of the original size), `min_width` specifies the minimum width constraint, and `min_height` specifies the minimum height constraint.

The function calculates the target size by multiplying the original dimensions by the percentage. It then checks if the new size is smaller than the minimum size and adjusts it accordingly. Finally, it resizes the image and saves it to the output path.

You can adjust the `input_image_path`, `output_image_path`, `percentage`, `min_width`, and `min_height` variables according to your needs. Ensure that the input image file exists and has the correct format, and the output path is writable.

Certainly! Here's an example that combines both resizing and converting an image to the WEBP format using Python with the Pillow library:

```python
from PIL import Image

def resize_and_convert_to_webp(input_image_path, output_image_path, new_width, new_height):
    image = Image.open(input_image_path)
    resized_image = image.resize((new_width, new_height))
    resized_image.save(output_image_path, "WEBP")

# Example usage
input_image_path = "input.jpg"
output_image_path = "output.webp"
new_width = 800
new_height = 600
resize_and_convert_to_webp(input_image_path, output_image_path, new_width, new_height)
```

In this updated code, the `resize_and_convert_to_webp` function takes four parameters: `input_image_path` specifies the path to the input image file, `output_image_path` specifies the path where the resized and converted image will be saved, `new_width` specifies the desired width of the resized image, and `new_height` specifies the desired height of the resized image.

The function uses `Image.open()` to open the input image, `image.resize()` to resize it to the specified dimensions, and `resized_image.save()` to save the resized image as a WEBP file.

You can adjust the `input_image_path`, `output_image_path`, `new_width`, and `new_height` variables according to your requirements. Ensure that the input image file exists and has the correct format, and the output path is writable. The resulting image will be resized to the specified dimensions and saved in the WEBP format.

So, we have to convert. 

du -h ../www/assets/images/landing/

5.5G    ../www/assets/images/landing/

-  5.5 G images from 
Count files in a folder linux shell

ls ../www/assets/images/landing/ -1 | wc -l

7033


Ok, 

But shall we keep all formats in a separate folder or in the same?

It's a good practice to organize your files in a structured manner, especially when dealing with different image formats. Keeping the converted images in a separate folder can help maintain clarity and avoid confusion. Here's an updated code that creates a separate folder for the converted images and saves them there:

```
   glob.glob('*.*')

   output_folder = "converted_images"


    # Create the output folder if it doesn't exist
    os.makedirs(output_folder, exist_ok=True)


    # Get the input image filename and construct the output image path
    input_filename = os.path.basename(input_image_path)
    output_image_path = os.path.join(output_folder, os.path.splitext(input_filename)[0] + ".webp")

```

glob.glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False)

list of path names that match pathname, which must be a string containing a path specification. pathname can be either absolute (like /usr/src/Python-1.5/Makefile) or relative (like ../../Tools/*/*.gif),
    
The `glob` function in Python is part of the `glob` module, which provides a convenient way to retrieve files and directories matching a specific pattern. It is often used for file searching and pattern matching in directories.

Here's the description of the `glob` function and its parameters:

```python
glob.glob(pathname, recursive=False)
```

- `pathname`: This parameter specifies the pattern or path to search for. It can include wildcards such as `*` (matches zero or more characters) and `?` (matches any single character). The `pathname` can also include directory names, allowing you to search for files in specific directories. For example, `"*.jpg"` matches all files with the `.jpg` extension in the current directory, while `"images/*.jpg"` matches all files with the `.jpg` extension in the `images` directory.
  
- `recursive` (optional): This parameter determines whether the search should be recursive or not. If set to `True`, the `glob` function searches for files in all subdirectories recursively. By default, it is set to `False`.
Subdirectory will be our webp_format os recursive have to be False. 

The `glob` function returns a list of paths that match the specified pattern. Each path represents a file or directory that matches the given pattern.

Here's an example that demonstrates the usage of `glob` to retrieve all text files in a directory:

```python
import glob

all_files = glob.glob("*.*")
print(all_files)
```

In this example, `glob.glob("*.*")` searches for all files in the current directory with the `.all` extensions. The function returns a list of paths that match the pattern, which is then printed to the console.

So, we have now all elements to write small command for Django project where we will convert all images to webp format and save new url in templates. 

vim page/management/commands/convert_images_to_webp.py 


File selection will be even easier since we have all images in one page model. In this way we can only read and check images.

Change templates 

vim /home/sites//www/templates/blog-include.html

vim /home/sites//www/templates/list_blog.html 

vim /home/sites//www/templates/blog.html 


What are the recommended minimum and maximum width and height for images on the web and mobile?


Determining the best minimum and maximum width and height for images on the web and mobile depends on various factors, including the target devices, user experience considerations, and specific requirements of your website or application. However, here are some general guidelines to consider:

Web:

1. Minimum width and height: A commonly used minimum size for web images is around 320 pixels, which ensures they are legible on small screens and responsive across different devices.

2. Maximum width: The maximum width can vary depending on the layout and design of your website. However, it is often recommended to limit the maximum width to around 1200-1600 pixels for most web pages. This helps prevent excessively large images that can impact page load times.

3. Maximum file size: Consider optimizing your images to reduce file sizes without compromising quality. Aim for file sizes that are as small as possible while still maintaining acceptable image quality. Techniques like image compression and using appropriate image formats (e.g., JPEG for photographs, PNG for graphics) can help reduce file sizes.

Mobile:

1. Minimum width and height: Considering the smaller screen sizes of mobile devices, it is recommended to use a minimum size of around 320 pixels for mobile images as well.

2. Maximum width: Mobile screens can vary significantly in size, so it's important to design images that scale well across different devices. A maximum width of 640-800 pixels is often sufficient for mobile images, ensuring they are not overly large and take advantage of high-density displays.

3. Retina and high-density displays: With the prevalence of high-resolution screens, you may consider providing higher-resolution versions (2x or 3x) of your images for devices with retina or high-density displays. This can enhance the visual quality and crispness of images on such devices.

Remember to test your images on different devices and screen sizes to ensure they are visually appealing and perform well across various platforms. Responsive design techniques, such as using CSS media queries, can help adapt image sizes and optimize the user experience for different devices.

What is best image size for google performance and Lighthouse report?

For optimal performance and a good Lighthouse report score on Google, it is recommended to follow the best practices for image sizes. Here are some guidelines to consider:

1. Image dimensions: Provide images with the exact dimensions required by your website or application. Avoid using larger images and relying on HTML or CSS to resize them. This reduces the need for the browser to perform additional resizing operations, resulting in faster load times.

2. Image compression: Compress your images to reduce file sizes without compromising quality. Use efficient compression techniques such as lossy compression (e.g., JPEG) for photographs and lossless compression (e.g., PNG) for graphics or images with transparency. Aim for a balance between file size reduction and maintaining acceptable visual quality.

3. File formats: Choose the appropriate file format for your images. JPEG is suitable for photographs or images with complex color gradients, while PNG is better for graphics, logos, or images with transparency. Consider using modern image formats like WebP, which offers superior compression while maintaining quality, especially for browsers that support it.

4. Responsive images: Implement responsive image techniques such as using the `srcset` attribute and the `<picture>` element. This ensures that appropriate images are served to different devices based on their capabilities and screen sizes. This can help reduce unnecessary image downloads for devices that don't require large images.

5. Lazy loading: Employ lazy loading techniques to defer the loading of images that are not immediately visible in the viewport. This can significantly improve initial page load times by prioritizing the loading of visible content.

6. Aspect ratio: Maintain the original aspect ratio of the images to prevent distortion or unexpected layout changes. Specify the width and height attributes in the HTML to reserve the required space for the images before they are loaded.

Remember to test your website or application with real-world scenarios, different network conditions, and across various devices using tools like Lighthouse or PageSpeed Insights. These tools can provide specific recommendations tailored to your site's performance. 
<picture>
  <source media="(max-width: 799px)" srcset="car-480w.webp" />
  <source media="(min-width: 800px)" srcset="car-800w.jpg" />
  <img src="car-800w.jpg" alt="Car example" />
</picture>
Here's an example of Python code using the Pillow library to resize an image to a width of 640 pixels while maintaining the proportional height:

```python
from PIL import Image

def resize_image_proportional(input_image_path, output_image_path, new_width):
    image = Image.open(input_image_path)
    width, height = image.size

    # Calculate the proportional height based on the new width
    new_height = int(height * new_width / width)

    # Resize the image
    resized_image = image.resize((new_width, new_height))
    resized_image.save(output_image_path)

# Example usage
input_image_path = "input.jpg"
output_image_path = "output.jpg"
new_width = 640
resize_image_proportional(input_image_path, output_image_path, new_width)
```

In this code snippet, the `resize_image_proportional` function takes three parameters: `input_image_path` specifies the path to the input image file, `output_image_path` specifies the path where the resized image will be saved, and `new_width` specifies the desired width of the resized image.

The function calculates the proportional height based on the ratio between the original width and the new width. Then, it uses `image.resize()` to resize the image to the specified width and proportional height. Finally, it saves the resized image to the output path.

You can adjust the `input_image_path`, `output_image_path`, and `new_width` variables according to your requirements. Make sure the input image file exists and has the correct format, and the output path is writable. The resulting image will have a width of 640 pixels and a height that maintains the original aspect ratio.

Update url for img src tag


```
import os
from urllib.parse import urlparse

file_name = os.path.splitext(os.path.basename(page.img.path))[0]
directory_path = os.path.dirname(page.img.path)


parsed_url = urlparse(page.img.url)
path = parsed_url.path
directory_path = "/".join(path.split("/")[:-1])

file_name = os.path.splitext(os.path.basename(path))[0]
web_img = directory_path + "/webp/" + file_name + ".webp"

# output /assets/images/landing/webp/couple-buying-new-car-showroom-man-gives-key-woman.webp
```

Django command for resizing and conversion

from django.conf import settings

from page.models import *

from django import db

from datetime import datetime

import sys, traceback

from bs4 import BeautifulSoup

import re

from django.template.defaultfilters import slugify

from PIL import Image

import os

from urllib.parse import urlparse

import glob



WIDTH = 640


class Command(BaseCommand):

    def handle(self, *args, **options):

        import pdb;pdb.set_trace()

        src = "/home/sites/img/Sergej_Dergatsjev.jpg"

        dist = "/home/sites/img/Sergej_Dergatsjev.webp"

        self.resize_img(src, dist)



    def resize_img(self, src, dist):

        image = Image.open(src)

        width, height = image.size

        new_height = int(height * WIDTH / width)

        resized_image = image.resize((WIDTH, new_height))

        resized_image.save(dist, format="webp")


WIDTH = 640

SOURCE_PATH = "/home/sites/images/"

DIST_PATH = "/home/sites/images/webp/"


class Command(BaseCommand):

    def handle(self, *args, **options):

        all_images = glob.glob(SOURCE_PATH + "*.*")

        for img in all_images:

            self.resize_img(img)


    def resize_img(self, img):

        image = Image.open(img)

        width, height = image.size

        new_height = int(height * WIDTH / width)

        resized_image = image.resize((WIDTH, new_height))

        file_name = os.path.splitext(os.path.basename(img))[0] + ".webp"

        resized_image.save(DIST_PATH + file_name, format="webp")

Comments