7

I want to resize png picture 476x402 to 439x371, and I used resize method of PIL(image) or opencv, however, it will loss some sharp. After resize, The picture becomes blurred. How to resize(shrink) image without losing sharpness with use python?

from skimage import transform, data, io
from PIL import Image
import os
import cv2

infile = 'D:/files/script/org/test.png'
outfile = 'D:/files/script/out/test.png'

''' PIL'''
def fixed_size1(width, height):
    im = Image.open(infile)
    out = im.resize((width, height),Image.ANTIALIAS)
    out.save(outfile)

''' open cv'''
def fixed_size2(width, height):
    img_array = cv2.imread(infile)
    new_array = cv2.resize(img_array, (width, height), interpolation=cv2.INTER_CUBIC)
    cv2.imwrite(outfile, new_array)


def fixed_size3(width, height):
    img = io.imread(infile)
    dst = transform.resize(img, (439, 371))
    io.imsave(outfile, dst)

fixed_size2(371, 439)

src:476x402

src:476x402

resized:439x371

resized:439x371

Adriaan
  • 17,741
  • 7
  • 42
  • 75
GGS of Future
  • 73
  • 1
  • 1
  • 4

2 Answers2

5

How can you pack 2000 pixels into a box that only holds 1800? You can't.

Putting the same amount of information (stored as pixels in your source image) into a smaller pixelarea only works by

  • throwing away pixels (i.e. discarding single values or by cropping an image which is not what you want to do)
  • blending neighbouring pixels into some kind of weighted average and replace say 476 pixels with slightly altered 439 pixels

That is exactly what happens when resizing images. Some kind of algorithm (interpolation=cv2.INTER_CUBIC, others here) tweaks the pixel values to merge/average them so you do not loose too much of information.

You can try to change the algorithm or you can apply further postprocessing ("sharpening") to enrich the contrasts again.

Upon storing the image, certain formats do "lossy" storage to minimize file size (JPG) others are lossless (PNG, TIFF, JPG2000, ...) which further might blur your image if you choose a lossy image format.


See

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • I tried other InterpolationFlags arg. it still get blur. and I just transform png, opencv has other method for Sharpen image, I trying use them to restore source as possible – GGS of Future Oct 10 '20 at 11:34
  • If I look at my image in, say, Windows Photo Viewer, and zoom and resize to make it fit the size of the thumbnail I generated in Pillow, the Windows Photo Viewer is always much sharper and crisper compared to Pillow. This is the problem I'm trying to address myself. – Bobort Aug 30 '22 at 20:43
  • @Bobort - Image optimizing is an artform ;) - you can try different ways to resize - you may want to look into "sharpening" filters afterwards - f.e. googling leads to https://pythonexamples.org/python-pillow-adjust-image-sharpness/ - but the result may vary between different imagesources and you may need to tweak parameters to get an "optimized" result. Starting with a non-compressed image format (not jpg, png or tif or ...) may help. Good luck :) – Patrick Artner Aug 31 '22 at 06:10
  • 1
    @PatrickArtner, I have done more investigation and discovered that my conclusion was wrong. Pillow generates the images just fine. The browser doesn't render them very crisply, however. In particular, these are chromium-based browsers. Firefox renders the image beautifully. I'm suspecting it is related to DPI or the font-size setting in Windows, and that chromium is doing something with that value that makes the picture fuzzy-looking. It's a ridiculous problem to have in 2022, but we're stuck with what we have. – Bobort Aug 31 '22 at 19:39
-1

If they are simple images convert the images to a SVG, reshape the SVG and convert it back to PNG.

LW001
  • 2,452
  • 6
  • 27
  • 36
vicky
  • 1