Сжатие изображений в react-native
Я пытаюсь сжать изображения с помощью mozjpeg, когда я реализовал его в node.js, согласно документам, он работал нормально.
const input = fs.readFileSync("in.ppm");
const out = mozjpeg.encode(input, { quality: 85 });
Мне нужно выполнить сжатие на стороне клиента, поэтому я попытался сделать то же самое с react-native, поскольку response-native не содержит модулей ядра, таких как fs, мне нужно использовать стороннюю библиотеку с response-native -fs для чтения файлов.
Когда я пытался выполнить mozjpeg.encode(input, { quality: 85 });
в react-native он бросает Unrecognized input file format --- perhaps you need -targa
реализация на стороне сервера
const mozjpeg = require("mozjpeg-js");
const fs = require("fs");
const input = fs.readFileSync(filePath);
const out = mozjpeg.encode(input, { quality: 85 });
console.error(out.stderr);
fs.writeFileSync("out.jpg", out.data);
реализация на стороне клиента
fs.readFile(image.path).then(data => {
const out = mozjpeg.encode(data, { quality: 85 });
console.log(out);
}
Вот список того, что я пробовал
- Пытался ввести ввод в шестнадцатеричном формате, буфере, base64 и простой строке URL.
- Поскольку URL-адрес Android содержит
file://
в качестве приставки я тоже пытался их удалить.
4 ответа
Кроме того, есть еще одна хорошая библиотека для выбора кадрирования изображений React-Native, цель которой - захват некоторых изображений и их обрезка, но у нее есть хорошая способность сжимать их. возможно, в этой библиотеке есть хороший алгоритм сжатия, например mozjpeg.
Он может открывать камеру, открывать галерею или использовать постоянное изображение, даже если вы можете отключить обрезку:
ImagePicker.openCamera({
width: 300,
height: 400,
compressImageQuality: 0.2
}).then(image => {
// do what you want
}).catch(e => {
// handle error
});
Хорошо настраивается и имеет множество вариантов настройки. Надеюсь, это вам поможет.
На самом деле я не знаю о mozjpeg
но я предпочитаю использовать чистый JavaScript способ решения проблемы в среде проблемы.
Я думаю, ваша мысль упала в одностороннем BIOS, оставьте решение NodeJS, вы находитесь в среде, поддерживающей реакцию, поэтому используйте React Native Compress Image или React Native Image Resizer.
Исходя из своего опыта, я предпочитаю использовать второй, React Native Image Resizer.
После установки используйте его, как показано ниже:
ImageResizer.createResizedImage(
imageUri,
newWidth,
newHeight,
compressFormat,
quality
)
.then( resizedImageUri => {
// the resizedImageUri is accessible here to use.
}).catch( err => {
// Catch any error here.
});
Вы можете найти в документе mozjpeg-js, что входным аргументом является:
типизированный массив или буфер данных
fs.readFile
тип возврата на стороне клиента (react-native-fs
) является Promise<string>
и вернуть содержимое. (Док)
Но на стороне сервера (fs
), fs.readFileSync
объект буфера возврата. ( Док)
Таким образом, вы можете изменить строку на типизированный массив с помощью этой функции:
function str2ta(str) {
var bufView = new Uint16Array(str.length*2); // 2 bytes for each char
for (var i=0, strLen=str.length; i<strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return bufView;
}
В Expo есть компонент, который делает именно это: Image Manipulator.