Оптимизация изображений
Уменьшение веса картинок перед тем, как класть их в письмо: тот же конвейер, через который проходят загрузки в файловый менеджер DashaMail.
Картинки — самая тяжёлая часть письма, и вес влияет не только на трафик: часть почтовых клиентов обрезает письмо целиком, а на мобильном интернете тяжёлая вёрстка просто не догружается. Эндпоинт прогоняет изображение через тот же конвейер, который DashaMail применяет к загрузкам в файловый менеджер.
Что происходит с картинкой:
- Геометрия. Если ширина больше 1600 px, изображение ужимается до этого потолка с сохранением пропорций. Прозрачность, анимация и ориентация из EXIF сохраняются.
- Пережатие. Кодек переупаковывает файл и снимает метаданные. По умолчанию — без потерь: пиксели остаются прежними до единого.
Формат никогда не меняется. JPEG остаётся JPEG, PNG — PNG. Это сделано намеренно: в письмах не работают ни WebP, ни AVIF, а подменить формат по согласованию с клиентом нельзя — в письме зашит статический адрес картинки.
Метод ничего не сохраняет: ни в вашем файловом менеджере, ни где-либо ещё результат не остаётся. Это чистое преобразование «прислали — получили обратно».
Оптимизировать изображение #
POST
/images/optimize
Принимает JPEG, PNG или GIF и возвращает облегчённую версию в том же формате вместе со статистикой: сколько весило, сколько стало и какие шаги сработали.
Если ужать не удалось — картинка уже оптимальна, нужного
кодека нет на сервере или результат получился больше исходника, —
метод возвращает файл без изменений и
changed: false. Ошибкой это не считается.
Как передать картинку. Либо полем
image в JSON — строка base64, допускается префикс
data:image/png;base64,. Либо как файл в
multipart/form-data, поле file:
curl -X POST 'https://api.dashamail.com/v2/images/optimize' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@photo.jpg'
Второй способ предпочтителен для крупных файлов: base64 раздувает тело запроса примерно на треть.
Параметры строки запроса
| Параметр | Тип | Описание |
|---|---|---|
response | string | Со значением binary метод отдаёт сами байты картинки с соответствующим Content-Type, а статистику кладёт в заголовки X-Imageopt-Original-Size, X-Imageopt-Size и X-Imageopt-Saved-Bytes. По умолчанию ответ приходит в обычном JSON-конверте. |
Параметры тела запроса
| Параметр | Тип | Описание |
|---|---|---|
image | string | Картинка в base64. Не нужен, если файл передан через multipart/form-data. |
resize | флаг | Ужимать ли по ширине. По умолчанию включено; 0 оставит исходную геометрию и выполнит только пережатие. |
max_width | integer | Другой потолок ширины вместо 1600 px. Допустимо от 16 до 20000. |
lossy | флаг | Разрешить пережатие с потерями. Даёт заметно меньший файл ценой небольшой потери качества; по умолчанию выключено. |
Что возвращается
Оптимизированную картинку в base64 (поле image)
и статистику обработки. Поле steps показывает,
что сработало на каждом из двух шагов, — полезно, когда
результат не совпал с ожиданием.
Возможные ошибки
| HTTP | code | Когда возникает |
|---|---|---|
422 |
3 |
Картинка не передана, image не является корректным base64, формат не JPEG/PNG/GIF либо max_width вне диапазона 16–20000 |
413 |
26 |
Картинка тяжелее 20 МиБ |
curl -X POST 'https://api.dashamail.com/v2/images/optimize' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"image": "iVBORw0KGgoAAAANSUhEUgAAA…",
"lossy": 1
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/images/optimize');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'image' => 'iVBORw0KGgoAAAANSUhEUgAAA…',
'lossy' => 1,
], JSON_UNESCAPED_UNICODE),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests
response = requests.post(
'https://api.dashamail.com/v2/images/optimize',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'image': 'iVBORw0KGgoAAAANSUhEUgAAA…',
'lossy': 1,
},
)
response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/images/optimize', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"image": "iVBORw0KGgoAAAANSUhEUgAAA…",
"lossy": 1
}),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
{
"response": {
"msg": {
"err_code": 0,
"text": "OK",
"type": "message"
},
"data": {
"format": "png",
"mime": "image/png",
"changed": true,
"steps": {
"resize": "already_narrow",
"compress": "pngquant"
},
"width": 900,
"height": 600,
"original_width": 900,
"original_height": 600,
"original_size": 812345,
"size": 279431,
"saved_bytes": 532914,
"saved_percent": 65.6,
"image": "iVBORw0KGgoAAAANSUhEUgAAA…"
}
}
}