Изменение размера изображения Base-64 в JavaScript без использования холста
Мне нужно изменить размеры изображений в JavaScript без использования элемента HTML.
Мое мобильное приложение для HTML делает снимки, а затем преобразует их в строки base64. После этого мне нужно изменить их размер до того, как они будут отправлены в API, чтобы сохранить место для хранения.
Я ищу другой и более подходящий способ изменить их размер, используя элемент canvas. Есть ли способ?
Ответы
Ответ 1
Способ избежать основного HTML-кода, который должен быть затронут, состоит в том, чтобы создать внеэкранный холст, который хранится вне DOM-дерева.
Это обеспечит битмап-буфера и собственный скомпилированный код для кодирования данных изображения. Это прямо необходимо сделать:
function imageToDataUri(img, width, height) {
// create an off-screen canvas
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
// set its dimension to target size
canvas.width = width;
canvas.height = height;
// draw source image into the off-screen canvas:
ctx.drawImage(img, 0, 0, width, height);
// encode image to data-uri with base64 version of compressed image
return canvas.toDataURL();
}
Если вы хотите создать другой формат, чем PNG (по умолчанию), просто укажите тип:
return canvas.toDataURL('image/jpeg', quality); // quality = [0.0, 1.0]
Стоит отметить, что ограничения CORS распространяются на toDataURL()
.
Если ваше приложение предоставляет только изображения с кодировкой base64 (я предполагаю, что они являются данными-uri с данными base64?), тогда вам нужно сначала загрузить изображение:
var img = new Image;
img.onload = resizeImage;
img.src = originalDataUriHere;
function resizeImage() {
var newDataUri = imageToDataUri(this, targetWidth, targetHeight);
// continue from here...
}
Если источник является чистой базой-64-строкой, просто добавьте заголовок к нему, чтобы сделать его data-uri:
function base64ToDataUri(base64) {
return 'data:image/png;base64,' + base64;
}
Просто замените часть image/png
на тип, который представляет строка base64 (т.е. сделайте это необязательным аргументом).
Ответ 2
Ответ Кена - правильный ответ, но его код не работает. Я сделал некоторые корректировки, и теперь он работает отлично. Чтобы изменить размер URI данных:
// Takes a data URI and returns the Data URI corresponding to the resized image at the wanted size.
function resizedataURL(datas, wantedWidth, wantedHeight)
{
// We create an image to receive the Data URI
var img = document.createElement('img');
// When the event "onload" is triggered we can resize the image.
img.onload = function()
{
// We create a canvas and get its context.
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// We set the dimensions at the wanted size.
canvas.width = wantedWidth;
canvas.height = wantedHeight;
// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);
var dataURI = canvas.toDataURL();
/////////////////////////////////////////
// Use and treat your Data URI here !! //
/////////////////////////////////////////
};
// We put the Data URI in the image src attribute
img.src = datas;
}
// Use it like that : resizedataURL('yourDataURIHere', 50, 50);
Ответ 3
Да, вы можете. Эти решения подходят для изменения размера не только для преобразования изображения в base64.
- Вы можете преобразовать файл js в растровое изображение изображения jpg-js. И вы можете изменить размер только этой библиотеки, но в случае изменение размера с очень большого изображения на очень небольшое, качество будет очень плохо. Лучший способ для изображений с высоким разрешением - преобразовать файл в растровое изображение по jpg-js, а затем изменить размер этого растрового изображения на Pica lib.
- Вы можете получить данные изображения из файла jpg-js (или нарисовать изображение на холсте), а затем изменить размер canvasImageData, изменив размер lib pica. (хорошо для изображений с высоким разрешением, без ограничения размера холста)
- Вы можете использовать экранный холст, не прикрепляя холст к телу и не изменяя размер изображения. Это решение будет быстрее, но будет худшим решением для изображений с высоким разрешением, например 6000х6000 пикселей. В этом случае результат canvas может быть с плохим качеством или просто пустым, или браузер может упасть с исключением ограничения памяти. (хорошо для нормальных и маленьких изображений)
Jpg-js и Pica вообще не будут использовать элементы dom. Эти библиотеки работают только с данными изображения, без элементов dom (холст и изображение).
О холсте, ограничении размера см. этот пост
Ответ 4
Пьеррик Мартельер - далеко не лучший ответ, я просто хотел бы отметить, что вы должны реализовать это с помощью асинхронной функции. После этого вы сможете сделать что-то вроде:
var newDataUri = await resizedataURL(datas,600,600);
Это будет ждать результата функции, прежде чем перейти к следующему шагу. Это более чистый способ написания кода. Вот функция от Pierrick с небольшим редактированием:
// Takes a data URI and returns the Data URI corresponding to the resized image at the wanted size.
function resizedataURL(datas, wantedWidth, wantedHeight){
return new Promise(async function(resolve,reject){
// We create an image to receive the Data URI
var img = document.createElement('img');
// When the event "onload" is triggered we can resize the image.
img.onload = function()
{
// We create a canvas and get its context.
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// We set the dimensions at the wanted size.
canvas.width = wantedWidth;
canvas.height = wantedHeight;
// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);
var dataURI = canvas.toDataURL();
// This is the return of the Promise
resolve(dataURI);
};
// We put the Data URI in the image src attribute
img.src = datas;
})
}// Use it like : var newDataURI = await resizedataURL('yourDataURIHere', 50, 50);
Для получения дополнительной информации вы можете проверить документы MDN: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise
Ответ 5
Вы можете использовать необработанную обработку изображений Base64, как показано здесь.
Выглядит сложно (и только для png) и почему многие предпочитают использовать холст
http://blog.calyptus.eu/seb/2009/05/png-parser-in-javascript/