پردازش تصاویر با Imgproxy
(Imgproxy one-click app)Imgproxy یک ابزار پردازش تصویر توسعه داده شده با زبان Go است که میتوانیم آن را جایگزینی مدرن و حتی بسیار کاربردیتر برای ImageMagick و یا GraphicsMagick بدانیم زیرا قابلیتهای مختلفی مانند تغییر اندازهی تصاویر را بهصورت remote برای ما فراهم کرده است.
فهرست عناوین:
- راهاندازی Imgproxy
- استفاده از Imgproxy بر روی فضای ذخیرهسازی ابری لیارا
- استفاده از Imgproxy در برنامههای Django
- استفاده از Imgproxy در برنامههای Laravel
- استفاده از Imgproxy در برنامههای NodeJS
- توضیحات و نکات تکمیلی
🚀 راهاندازی Imgproxy
در صورتی که تمایلی به خواندن آموزش متنی ندارید میتوانید ویدیوی آموزشی زیر را مشاهده کنید.
برای راهاندازی برنامهی آماده Imgproxy باید در بخش برنامههای کنسول لیارا بر روی دکمهی ایجاد برنامه کلیک کرده و در صفحهی باز شده وارد بخش برنامههای آماده شوید. سپس برنامهی Imgproxy را انتخاب و یک شناسهی یکتا برای برنامهی خود درنظر بگیرید، همچنین پلن مورد نظر خود را انتخاب کنید و در آخر بر روی دکمهی ایجاد برنامه کلیک کنید.
استفاده از Imgproxy بر روی فضای ذخیرهسازی ابری لیارا
برای استفاده از Imgproxy بر روی عکسهای ذخیرهشده در فضای ذخیرهسازی ابری لیارا نیاز به انجام هیچکار خاصی نیست؛ فقط کافیست تا آدرس دائمی (یا موقت) عکس ذخیره شده را در انتهای URL پیکربندی شده Imgproxy قرار دهید؛ به عنوان مثال، فرض کنید که این URL برابر با مقدار زیر است:
https://imgproxy-app.liara.run/_/resize:fill:300:400:0/gravity:sm/plain/
حال، فرض کنیم که URL عکس ذخیرهشده در لیارا نیز، برابر با مقدار زیر است:
https://bucket.storage.iran.liara.space/liara-poster.png
اکنون، برای اعمال Imgproxy بر روی عکس مد نظر خود، کافیست تا URL پیکربندی شده Imgproxy را قبل از URL عکس مدنظر خود قرار دهید:
https://imgproxy-app.liara.run/_/resize:fill:300:400:0/gravity:sm/plain/https://bucket.storage.iran.liara.space/liara-poster.png
بدین نحو، تمامی تغییرات اعمال میشوند و شما میتوانید با استفاده از URL فوق، به عکس نهایی خود دسترسی داشته باشید. قطعه کد زیر، نمونهای از استفاده imgproxy بر روی باکت لیارا در فریمورک Flask است:
from flask import Flask, request, render_template, redirect, url_for
import boto3
import uuid
from dotenv import load_dotenv
import os
app = Flask(__name__)
# Load environment variables from .env file
load_dotenv()
LIARA_ENDPOINT = os.getenv("LIARA_ENDPOINT")
LIARA_BUCKET_NAME = os.getenv("LIARA_BUCKET_NAME")
LIARA_ACCESS_KEY = os.getenv("LIARA_ACCESS_KEY")
LIARA_SECRET_KEY = os.getenv("LIARA_SECRET_KEY")
IMGPROXY_URL = os.getenv("IMGPROXY_URL")
img_proxy_conf = {
"signature": "_",
"options": "resize:fill:300:400:0",
"gravity": "gravity:sm",
}
imgproxy_conf = f'{img_proxy_conf["signature"]}/{img_proxy_conf["options"]}/{img_proxy_conf["gravity"]}/plain'
s3 = boto3.client('s3',
endpoint_url=LIARA_ENDPOINT,
aws_access_key_id=LIARA_ACCESS_KEY,
aws_secret_access_key=LIARA_SECRET_KEY)
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['file']
if file:
# Generate a unique filename using UUID
filename = str(uuid.uuid4()) + '.' + file.filename.rsplit('.', 1)[1]
# Save file to S3
s3.upload_fileobj(file, LIARA_BUCKET_NAME, filename)
# Generate the URL for the uploaded file
url = f"{LIARA_ENDPOINT}/{LIARA_BUCKET_NAME}/{filename}"
# Redirect to images page
return redirect(url_for('images'))
return render_template('index.html')
@app.route('/images')
def images():
# List all objects in the bucket
response = s3.list_objects_v2(Bucket=LIARA_BUCKET_NAME)
images = []
for obj in response.get('Contents', []):
images.append(f"{IMGPROXY_URL}{imgproxy_conf}/{LIARA_ENDPOINT}/{LIARA_BUCKET_NAME}/{obj['Key']}")
return render_template('images.html', images=images)
if __name__ == '__main__':
app.run(debug=True)
برای کسب اطلاعات بیشتر و اعمال دیگر تغییرات میتوانید مستندات پیکربندی Imgproxy را مطالعه کنید.
استفاده از Imgproxy در برنامههای Django
برای استفاده از Imgproxy در برنامههای Django، نیاز به نصب ماژول و یا کتابخانه خاصی نیست! در ادامه، یک مثال از نحوه استفاده Imgproxy آمده است:
در ابتدا، کافیست تا متغیرهای ENDPOINT و IMGPROXY_URL را به شکل زیر به فایل settings.py اضافه کنید:
import os
ENDPOINT = os.getenv("ENDPOINT", 'http://127.0.0.1:8000')
IMGPROXY_URL = os.getenv("IMGPROXY_URL", "")
برای مثال، اگر که از فایل .env استفاده میکنید، مقادیر دو متغیر فوق را باید همانند مقادیر زیر وارد کنید:
ENDPOINT=https://django-app-test.liara.run
IMGPROXY_URL=https://imgproxy-app.liara.run
اکنون میتوانید از Imgproxy در برنامه خود استفاده کنید؛ برای مثال، قطعه کد زیر در فایل models.py به کار رفته است:
from django.db import models
from django.conf import settings
img_proxy_conf = {
"signature": "_",
"options": "resize:fill:300:400:0",
"gravity": "gravity:sm",}
class Image(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(upload_to='')
full_path = models.CharField(max_length=255)
final_result = models.CharField(max_length=255)
def save(self, *args, **kwargs):
if self.image:
self.full_path = f"{settings.ENDPOINT}{self.image.url}"
if settings.IMGPROXY_URL != "":
self.final_result = (
f"{settings.IMGPROXY_URL}/{img_proxy_conf['signature']}/"
f"{img_proxy_conf['options']}/{img_proxy_conf['gravity']}/plain/"
f"{self.full_path}")
else:
self.final_result = self.image.url
super().save(*args, **kwargs)
در نظر داشته باشید که کد فوق، یک مثال از کاربرد Imgproxy است و شما میتوانید فیلد option درون دیکشنری img_proxy_conf موجود در کد فوق را با توجه به نیاز خود تغییر دهید.
استفاده از Imgproxy در برنامههای Laravel
برای استفاده از Imgproxy در ابتدا بایستی متغیرهای محیطی زیر را به فایل .env یا بخش متغیرهای محیطی برنامه خود اضافه کنید:
ENDPOINT_URL=your-host-address
IMGPROXY_URL=your-imgproxy-address
قطعه کد زیر یک مثال برای مقدار این متغیرهای محیطی است:
ENDPOINT_URL=https://laravel-app.liara.run
IMGPROXY_URL=https://imgproxy-app.liara.run
اکنون کافیست تا در دایرکتوری config یک فایل به نام custom.php ایجاد کنید و قطعه کد زیر را درون آن قرار دهید:
<?php
return [
'img_proxy_conf' => [
'signature' => '_',
'options' => 'resize:fill:300:400:0',
'gravity' => 'gravity:sm',
],
];
دقت داشته باشید که مقادیر درون img_proxy_conf برای مثال آورده شدهاند و شما میتوانید مقادیر آن را متناسب با نیازهای خود تغییر دهید.
اکنون، میتوانید از imgproxy در برنامه خود استفاده کنید؛ قطعه کد زیر، مثالی از استفاده imgproxy در کنترلر برنامه laravel است:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppModelsPhoto;
use IlluminateSupportFacadesStorage;
class PhotoController extends Controller
{
public function store(Request $request)
{
$request->validate([
'photo' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$imgProxyConf = config('custom.img_proxy_conf');
$options = $imgProxyConf['options'];
$gravity = $imgProxyConf['gravity'];
$signature = $imgProxyConf['signature'];
$phototemp = $request->file('photo')->store('public/photos');
$photoPath_ = env('ENDPOINT_URL') . Storage::url($phototemp);
$photoPath = env('IMGPROXY_URL') . '/' . $signature . '/' . $options . '/' . $gravity . '/plain/' . $photoPath_;
Photo::create([
'path' => $photoPath,
]);
return redirect()->route('photo.index');
}
public function index()
{
$photos = Photo::all();
return view('photos.index', compact('photos'));
}
}
استفاده از Imgproxy در برنامههای NodeJS
برای استفاده از Imgproxy باید همانند دو پلتفرم دیگر، متغیرهای محیطی زیر را به فایل .env یا بخش متغیرهای محیطی برنامه خود اضافه کنید:
ENDPOINT_URL=https://laravel-app.liara.run
IMGPROXY_URL=https://imgproxy-app.liara.run
اکنون میتوانید تنظیمات مربوط به Imgproxy را در برنامه خود وارد کنید:
const ENDPOINT_URL = process.env.ENDPOINT_URL;
const IMGPROXY_URL = process.env.IMGPROXY_URL;
const img_proxy_conf = {
"signature": "_",
"options": "resize:fill:300:400:0",
"gravity": "gravity:sm"
};
const imgproxy_conf = `${IMGPROXY_URL}/${img_proxy_conf.signature}/${img_proxy_conf.options}/${img_proxy_conf.gravity}/plain/`;
دقت داشته باشید که مقادیر درون img_proxy_conf برای مثال آورده شدهاند و شما میتوانید مقادیر آن را متناسب با نیازهای خود تغییر دهید.
در نهایت، میتوانید با استفاده از قطعه کد زیر، از imgproxy در برنامه خود استفاده کنید:
app.get('/images', (req, res) => {
fs.readdir('./public/uploads', (err, files) => {
if (err) {
console.error('Error reading directory:', err);
res.status(500).send('Internal Server Error');
return;
}
const imageFiles = files.filter(file => {
const extname = path.extname(file);
return ['.jpg', '.jpeg', '.png', '.gif'].includes(extname.toLowerCase());
});
const processedImages = imageFiles.map(image => {
const temp = `${ENDPOINT_URL}/public/uploads/${image}`;
return `${imgproxy_conf}${temp}`;
});
processedImages.forEach(image => {
console.log(image);
});
res.render('images', { images: processedImages });
});
});
🎯 توضیحات و نکات تکمیلی
اضافه کردن URL signature
بسیار توصیه میشود که در حالت Production با اجرای دستور زیر، یک hex-encoded key و یک hex-encoded salt ایجاد کرده و هر دوی این مقدارها را کپی کنید:
echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
سپس وارد تب برنامهها شده و برنامهی Imgproxy خود را انتخاب کنید. اکنون باید مقادیر کپی شده را در بخش تنظیمات متغیرها در فیلد Value متغیرهای IMGPROXY_KEY و IMGPROXY_SALT قرار دهید و درنهایت بر روی دکمهی ثبت تغییرات کلیک کنید.
محدود کردن دسترسی به Imgproxy با تنظیم IMGPROXY_SECRET
برای محدود کردن دسترسی به برنامهی Imgproxy میتوانید secret مورد نظر خود را در فیلد Value متغیر IMGPROXY_SECRET وارد کرده و درنهایت بر روی دکمهی ثبت تغییرات کلیک کنید.
تغییر نسخهی برنامه مستقر شده
برخی مواقع لازم شده که نسخه برنامهی آمادهای که مستقر کردیم رو تغییر بدیم. برای مثال، نسخه جدیدی از آن برنامه منتشر شده و ما میخواهیم از آن استفاده بکنیم. نکتهای که باید قبل تغییر نسخه برنامهمان در نظر داشته باشیم، این است که آن نسخه با لیارا سازگاری داشته باشد و در صورتی که لازم باشد از دیسکها برای مواردی همچون تغییرات در برنامه یا نگهداری اطلاعاتمان استفاده بکنیم. یا حتی لازم باشد یک سری متغیرهایی در برنامهمان تنظیم کنیم. در اینجا شما میتونید یک نمونه ساده از تغییر نسخه را مشاهده کنید. برای شروع لازم هست ابتدا در سیستم لوکال فایلی تحت عنوان liara.jsonایجاد کنید و مقادیر زیر رو در اون قرار بدید:
{
"image": "darthsim/imgproxy:<your-version>",
"port": 80,
"app": "<your-app-name>"
}
در اینجا مقدار app، برابر هست با نام برنامهای که در لیارا ایجاد کردید و مقدار image، برابر هست نام image برنامهتان. در قسمت port، پورتی که برنامهتان بر روی آن اجرا میشود. در نهایت با liara-cli و سپس دستور زیر برنامهتان مستقر کنید:
liara deploy