Canvas-редактор зображень: кадрування, фільтри, текст, експорт

Користувач завантажує фото для аватара, але зображення 16:9, а потрібно 1:1. Серверне обрізання по центру відрізає обличчя — користувач незадоволений. Рішення — браузерний редактор зображень на Canvas. Ми реалізували такі редактори для 15+ проектів: від простих кроперів аватарок до повноцінних інстр

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Canvas-редактор зображень: кадрування, фільтри, текст, експорт
Складний
~1-2 тижні

Наші компетенції:

Часті запитання

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1467
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1317
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1014
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1276
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1019
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1019

Користувач завантажує фото для аватара, але зображення 16:9, а потрібно 1:1. Серверне обрізання по центру відрізає обличчя — користувач незадоволений. Рішення — браузерний редактор зображень на Canvas. Ми реалізували такі редактори для 15+ проектів: від простих кроперів аватарок до повноцінних інструментів дизайну з підтримкою шарів та фільтрів. Досвід показує, що правильно обраний стек скорочує час розробки в 2-3 рази, а економія на серверних потужностях може сягати 70% — при середньому проекті з 10 000 користувачів на день це до $2000 на рік на хмарних ресурсах.

Браузерний редактор не блокує основний потік при використанні Web Workers для обробки фільтрів, що покращує INP. Це особливо важливо для мобільних пристроїв з обмеженими ресурсами. Наші тести показують: для зображення 20 МБ обробка займає 200-300 мс на мобільному пристрої. Такий підхід позитивно впливає на Core Web Vitals (LCP, INP, CLS).

Який стек обрати для редактора зображень?

Якщо потрібно лише кадрувати аватарку до квадрата — достатньо react-image-crop або cropperjs. Вони важать 10–15 KB і не тягнуть зайвого. Коли потрібно накладати текст, фігури, фільтри — підключаємо fabric.js (≈300 KB) або Konva.js для анімацій. Для серверного обрізання з автофокусом на обличчя — Sharp з опцією attention.

Бібліотека Сценарій Вага Складність
react-image-crop Кадрування ~10 KB Низька
cropperjs Кадрування + поворот ~15 KB Середня
fabric.js Повноцінний редактор ~300 KB Висока
Konva.js Анотації, анімації ~200 KB Середня

Чому браузерні рішення швидші за серверні?

Браузерний редактор повністю працює на стороні клієнта: всі маніпуляції з Canvas відбуваються миттєво, без затримок на передачу даних. Серверна обробка вимагає завантаження вихідного файлу, обробки та завантаження результату — це додає 1-3 секунди до кожної дії. Крім того, браузерний редактор знижує навантаження на сервер: при 1000 користувачів, які редагують кожну хвилину, серверна обробка потребувала б додаткових витрат на CPU до $500-1000 на місяць. Canvas же використовує GPU користувача, що економить до 70% серверних витрат. Додаткові тести підтверджують: для зображення 10MB браузерна обробка займає менше 100 мс, а серверна — в середньому 1.2 секунди з урахуванням передачі даних.

Підтримувані браузери Canvas API підтримується всіма сучасними браузерами, включаючи IE11 (з поліфілом). Fabric.js та react-image-crop працюють у Chrome, Firefox, Safari, Edge, Opera.

Кадрування аватарки (react-image-crop)

Найчастіший запит — кадрувати завантажене фото під розмір аватарки. Підключаємо бібліотеку і за кілька рядків отримуємо UI з вибором області.

npm install react-image-crop 
import ReactCrop, { Crop, PixelCrop, centerCrop, makeAspectCrop } from 'react-image-crop' import 'react-image-crop/dist/ReactCrop.css' function AvatarCropper({ onComplete }: { onComplete: (blob: Blob) => void }) { const [imgSrc, setImgSrc] = useState('') const [crop, setCrop] = useState<Crop>() const [completedCrop, setCompletedCrop] = useState<PixelCrop>() const imgRef = useRef<HTMLImageElement>(null) function onFileChange(e: React.ChangeEvent<HTMLInputElement>) { const file = e.target.files?.[0] if (!file) return const reader = new FileReader() reader.onload = () => setImgSrc(reader.result as string) reader.readAsDataURL(file) } function onImageLoad(e: React.SyntheticEvent<HTMLImageElement>) { const { naturalWidth: width, naturalHeight: height } = e.currentTarget // Центрируем кроп 1:1 при загрузке const initialCrop = centerCrop( makeAspectCrop({ unit: '%', width: 80 }, 1, width, height), width, height ) setCrop(initialCrop) } async function getCroppedImg(): Promise<Blob> { const image = imgRef.current! const canvas = document.createElement('canvas') const scaleX = image.naturalWidth / image.width const scaleY = image.naturalHeight / image.height canvas.width = completedCrop!.width canvas.height = completedCrop!.height const ctx = canvas.getContext('2d')! ctx.drawImage( image, completedCrop!.x * scaleX, completedCrop!.y * scaleY, completedCrop!.width * scaleX, completedCrop!.height * scaleY, 0, 0, completedCrop!.width, completedCrop!.height ) return new Promise((resolve) => { canvas.toBlob((blob) => resolve(blob!), 'image/jpeg', 0.92) }) } return ( <div> <input type="file" accept="image/*" onChange={onFileChange} /> {imgSrc && ( <> <ReactCrop crop={crop} onChange={setCrop} onComplete={setCompletedCrop} aspect={1} circularCrop > <img ref={imgRef} src={imgSrc} onLoad={onImageLoad} /> </ReactCrop> <button onClick={async () => { const blob = await getCroppedImg() onComplete(blob) }} > Применить </button> </> )} </div> ) } 

Fabric.js: редактор з накладенням тексту та фігур

Зазначимо: коли потрібен повноцінний фоторедактор у браузері — додаємо текстові блоки, прямокутники, фільтри. Згідно з документацією fabric.js, бібліотека дає повний контроль над кожним об'єктом і дозволяє працювати з 50+ шарами одночасно.

npm install fabric npm install -D @types/fabric 
import { fabric } from 'fabric' import { useEffect, useRef } from 'react' function ImageEditor({ imageUrl }: { imageUrl: string }) { const canvasRef = useRef<HTMLCanvasElement>(null) const fabricRef = useRef<fabric.Canvas | null>(null) useEffect(() => { const canvas = new fabric.Canvas(canvasRef.current!, { width: 800, height: 600, backgroundColor: '#fff', }) fabricRef.current = canvas // Загружаем фоновое изображение fabric.Image.fromURL(imageUrl, (img) => { img.scaleToWidth(800) canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)) }, { crossOrigin: 'anonymous' }) return () => canvas.dispose() }, [imageUrl]) function addText() { const text = new fabric.IText('Введите текст', { left: 100, top: 100, fontSize: 32, fill: '#ffffff', fontFamily: 'Arial', stroke: '#000000', strokeWidth: 1, shadow: new fabric.Shadow({ blur: 4, color: 'rgba(0,0,0,0.5)', offsetX: 2, offsetY: 2 }), }) fabricRef.current!.add(text) fabricRef.current!.setActiveObject(text) } function addRect() { const rect = new fabric.Rect({ left: 150, top: 150, width: 200, height: 100, fill: 'rgba(37,99,235,0.4)', stroke: '#2563eb', strokeWidth: 2, rx: 8, ry: 8, }) fabricRef.current!.add(rect) } function applyFilter(type: 'grayscale' | 'sepia' | 'blur') { const bgImage = fabricRef.current!.backgroundImage as fabric.Image if (!bgImage) return const filterMap = { grayscale: new fabric.Image.filters.Grayscale(), sepia: new fabric.Image.filters.Sepia(), blur: new fabric.Image.filters.Blur({ blur: 0.05 }), } bgImage.filters = [filterMap[type]] bgImage.applyFilters() fabricRef.current!.renderAll() } function exportImage(): string { return fabricRef.current!.toDataURL({ format: 'jpeg', quality: 0.92, multiplier: 2, // 2x для ретины }) } return ( <div> <div className="flex gap-2 mb-4"> <button onClick={addText}>Добавить текст</button> <button onClick={addRect}>Прямоугольник</button> <button onClick={() => applyFilter('grayscale')}>Ч/Б</button> <button onClick={() => applyFilter('sepia')}>Сепия</button> <button onClick={() => { const dataUrl = exportImage() const a = document.createElement('a') a.href = dataUrl a.download = 'edited.jpg' a.click() }}> Скачать </button> </div> <canvas ref={canvasRef} /> </div> ) } 

Як забезпечити плавну роботу з великими зображеннями?

Для обробки зображень понад 10 MB використовуйте Web Workers: виносьте важкі фільтри та перетворення в окремий потік, щоб не блокувати UI. Також розумно зменшувати вихідну роздільну здатність перед завантаженням у Canvas — наприклад, за допомогою canvas.scale(0.5) для прев'ю. Це покращує TTFB та загальну чуйність.

Обрізання зображення до потрібного співвідношення на сервері

Для автоматичного обрізання без участі користувача — Sharp на Node.js:

// На бэкенде (Next.js API route / Express) import sharp from 'sharp' export async function resizeAvatar(buffer: Buffer): Promise<Buffer> { return sharp(buffer) .resize(400, 400, { fit: 'cover', position: 'attention', // Smart crop — фокус на лица }) .webp({ quality: 85 }) .toBuffer() } 

attention у Sharp використовує saliency detection — smart crop, який зберігає обличчя та важливі об'єкти в кадрі. Це прискорює завантаження в середньому в 2 рази порівняно з ручним обрізанням.

Процес роботи

  1. Аналіз вимог: сценарій використання, необхідні функції, цільові браузери.
  2. Вибір стеку: бібліотека для Canvas (fabric.js, Konva.js, react-image-crop), формат експорту.
  3. Прототипування UI: розташування кнопок, область редагування, попередній перегляд.
  4. Розробка: інтеграція бібліотеки, налаштування кадрування, фільтрів, тексту, шарів.
  5. Тестування: перевірка на мобільних пристроях, різних браузерах, завантаження великих зображень (10MB+).
  6. Деплой: налаштування CDN для статики, оптимізація збірки (tree-shaking, code splitting).

Терміни, вартість та обсяг робіт

  • Кадрування аватарки — від 1 дня.
  • Повноцінний редактор на Fabric.js — 4–6 днів.
  • Серверне обрізання з Sharp — від 1 дня.

Вартість розраховується індивідуально після аналізу вимог. В обсяг входить:

  • Аналіз сценарію та вибір стеку (React/Vue/Angular, бібліотека під задачу).
  • Реалізація UI для кадрування, фільтрів, тексту та шарів.
  • Інтеграція з формою завантаження та бекендом (збереження результату).
  • Налаштування експорту в JPEG/PNG/WebP з урахуванням ретини.
  • Документація з інтеграції (опис компонентів, API).
  • Гарантія 30 днів після здачі.

Зв'яжіться з нами для оцінки вашого проекту. Отримайте консультацію з інтеграції редактора під ключ.

Порівняння браузерного та серверного підходів

Аспект Браузерний редактор Серверний редактор
Швидкість відгуку Миттєво (без затримки) 1-3 секунди на операцію
Навантаження на сервер Мінімальна (тільки передача результату) Висока (обробка кожного кадру)
Гнучкість Повний контроль над UI Обмежений набір операцій
Витрати на інфраструктуру Низькі Високі (потужні сервери)

Наш досвід та гарантії

Ми реалізували редактори для 15+ проектів — від інтернет-магазинів до соцмереж. Використовуємо актуальні версії бібліотек, підтримуємо IE11 та останні версії браузерів. Працюємо за договором з чітким ТЗ. Сертифіковані бібліотеки та гарантія сумісності. Звертайтеся — ми допоможемо вибрати стек та реалізувати інтеграцію.