I'm trying to make a distortion effect, but if we use the "convert" function using the command line, it requires us to specify the path to the file we are going to convert and at the end the name of the final image. I wanted to try to make the input image from bytesio or just bytesarray
here's my attempt but unfortunately it didn't work out(, it say like Wrong parameter: -liquid-rescale
# Distort function using imagemmagick
def distort(image, x=45, y=45):
img = Image.open(BytesIO(image))
w, h = img.size
command = [
"convert",
"pipe:0", # Input from stdin
"-liquid-rescale", f"{x}x{y}%!",
"-resize", f"{w}x{h}!",
"pipe:1", # Output to stdout
]
try:
process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout, stderr = process.communicate(image)
if process.returncode != 0:
logger.info(f"ImageMagick error: {stderr.decode(encoding="latin-1")}")
return None
return stdout
except Exception:
import traceback
traceback.print_exc()
return None
Your question could do with more context showing what your images are like (size, format etc) and how you plan to use your code. If my answer is insufficient, update your question and I will try to update my answer to match.
The problem appears to be that you are using ffmpeg
-style descriptors for input and output (i.e. pipe:0
and pipe:1
) rather than what ImageMagick expects, which is a dash/hypen, or an fd
number. So, to read a TIFF from stdin
and create a JPEG, use:
cat image.tif | magick - result.jpg
Or you can use:
cat image.tif | magick fd:0 result.jpg
Or you can use:
cat image.tif | magick /dev/stdin result.jpg
Note that the last option will probably not work on Windows, whereas the first 2 probably will.
However, that is not the whole story. You may want to force ImageMagick to write a JPEG or a PNG on stdout
. You can do that by prepending a format specifier to the output file like this - note that I am redirecting to a file to avoid making a mess in your Terminal:
magick image.tif JPEG:- > file.jpg
Or:
magick image.tif PNG:- > file.png
Note that you can force specific types of PNG, such as 8-bit, 16-bit, palette, RGBA by reading my answer here.
In concrete terms, your inner code should look more like this:
command = [
"convert",
"-", # Input from stdin
"-liquid-rescale", f"{x}x{y}%!",
"-resize", f"{w}x{h}!",
"PNG:-", # Output PNG to stdout
]
Note also that there are Python bindings directly to ImageMagick via wand so you can avoid all this jiggery-pokery with subprocesses using that.