Hola,
Quiero usar la API web para pyvips.
Pero realmente mal desempeño. ¿Dónde cometo errores?
Mi código está siguiendo;
hola.py
from flask import Flask
from Image import ImageTransform
from flask import request
from flask import send_file
import io
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
@app.route("/image")
def image():
image_value = request.args.get('image')
i = ImageTransform(image_value)
i.set_transform()
a = i.image.write_to_buffer('.jpeg')
return send_file(io.BytesIO(a), mimetype='image/jpg')
Image.py
import pyvips
import math
class ImageTransform(object):
image = None
def __init__(self, file_name):
self.image = pyvips.Image.new_from_file(file_name, access='sequential')
def set_resize_transform(self, width, height):
im = self.image
mem = im.write_to_buffer('.jpeg[Q=80]')
im = pyvips.Image.thumbnail_buffer(mem, width, height=height)
im = im.bandjoin(255)
im = im.gravity("centre", width, height,
extend="background",
background=[244, 244, 244, 255])
self.image = im
pass
def set_ratio_and_watermark_transform(self):
im = self.image
# ##### ######
# Trigonometry: Tangent = Opposite / Adjacent
tangent = im.height/im.width
# convert arctangent to degrees
angle = math.atan(tangent)*(180/math.pi);
water_mark_x = 140
water_mark_y = 140
water_mark_len = 16
# a^2 = b^2 + c^2 ; a = sqrt(b^2 + c^2)
half_hypotenuse = math.sqrt(im.height*im.height + im.width*im.width)/2;
font_size = int(math.hypot(im.height, im.width)/math.hypot(water_mark_x, water_mark_y)*(4 + int(water_mark_len/2)))
text = pyvips.Image.text("text text text", font = "Futura Medium", align='centre', width = 500, dpi = (font_size*4))
text = text.linear(0.3, 0)
text = text.similarity(angle=angle)
x = (im.width-text.width)/2
y = (im.height-text.height)/2
text = text.embed(x, y, text.width + x, text.height + y, extend="copy")
w = im.width if text.width > im.width else text.width
h = im.height if text.height > im.height else text.height
im = text.ifthenelse(255, im, blend=True)
self.image = im
def set_transform(self, type=int):
self.set_ratio_and_watermark_transform()
self.set_resize_transform(600, 450)
def write_image(self,dest_name):
self.image.write_to_file(dest_name)
`` bash
FLASK_APP = hello.py matraz ejecutar
```bash
ab -c 10 -n 10 http://54.229.246.74/image\?image\=foto.jpeg
Hola @volkan ,
Reorganizaría su canalización a algo como:
thumbnail
para abrir la imagen y reducir el tamaño en una sola operacióngravity
para agregar el fondoTe daré un ejemplo.
Aquí hay un programa de prueba que ejecuta su código y una posible nueva canalización. Cambié la línea tangente en su versión a:
tangent = float(im.width) / im.height
Pero por lo demás inalterado.
import time
import sys
import math
import pyvips
from Image import ImageTransform
start = time.time()
i = ImageTransform(sys.argv[1])
i.set_transform()
i.write_image(sys.argv[2])
end = time.time()
print "ImageTransform() took ", end - start
start = time.time()
target_width = 600
target_height = 450
# efficiently load and downsize in one operation
im = pyvips.Image.thumbnail(sys.argv[1], target_width, height=target_height)
# watermark
tangent = float(im.width) / im.height
angle = math.atan(tangent) * (180 / math.pi)
water_mark_x = 140
water_mark_y = 140
water_mark_len = 16
half_hypotenuse = math.sqrt(im.height*im.height + im.width*im.width)/2;
font_size = int(math.hypot(im.height, im.width)/math.hypot(water_mark_x, water_mark_y)*(4 + int(water_mark_len/2)))
text = pyvips.Image.text("text text text", font = "Futura Medium", align='centre', width = 500, dpi = (font_size*4))
text = text.linear(0.3, 0)
text = text.similarity(angle=angle)
x = (im.width - text.width) / 2
y = (im.height - text.height) / 2
text = text.embed(x, y, text.width + x, text.height + y, extend="copy")
w = im.width if text.width > im.width else text.width
h = im.height if text.height > im.height else text.height
im = text.ifthenelse(255, im, blend=True)
# add alpha and margins
im = im.bandjoin(255)
im = im.gravity("centre", target_width, target_height,
extend="background",
background=[244, 244, 244, 255])
im.write_to_file(sys.argv[2])
end = time.time()
print "after revision, took ", end - start
En esta computadora portátil con una imagen de 6k x 4k, veo:
$ python volkan.py ~/pics/theo.jpg x.jpg
ImageTransform() took 0.490525960922
after revision, took 0.0774891376495
Podrías hacer que tu código de marca de agua sea un poco más simple, lo intentaré.
Creo que agregaría la marca de agua así:
# in libvips 8.6, you can get text to automatically size to fill a rectangle
text = pyvips.Image.text("text text text",
font="Futura Medium", align="centre",
width=300, height=300)
# scale down brightness, then back to 8 bit ... this will avoid float arithmetic
# for the rotate/expand/ifthenelse
text = (text * 0.3).cast("uchar")
tangent = float(im.width) / im.height
angle = math.atan(tangent) * (180 / math.pi)
text = text.similarity(angle=angle)
text = text.gravity("centre", target_width, target_height)
im = text.ifthenelse(255, im, blend=True)
Así que eso es usar la nueva función "ajustar el tamaño del texto al cuadro" en 8.6, usando x * 0.3
lugar de linear
(hacen lo mismo, la sobrecarga del operador es más fácil de leer), manteniendo el texto como 8 bits para evitar que flote más tarde, y usar gravity
para hacer que embed
un poco más simple.
@jcupitt sus ejemplos son muy útiles. Gracias.
¡Bien, cerraré!
Comentario más útil
Creo que agregaría la marca de agua así:
Así que eso es usar la nueva función "ajustar el tamaño del texto al cuadro" en 8.6, usando
x * 0.3
lugar delinear
(hacen lo mismo, la sobrecarga del operador es más fácil de leer), manteniendo el texto como 8 bits para evitar que flote más tarde, y usargravity
para hacer queembed
un poco más simple.