Képek átméretezése és konvertálása
A Total.js a GraphicsMagick (gm) vagy az ImageMagick hívásával dolgozza fel a képeket, amelyeknek telepítve kell lenniük a szerveren (brew install graphicsmagick, apt install graphicsmagick). A $imageconverter beállítás választja ki a programot: gm (alapértelmezett), im vagy magick.
Az Image.load(filename) (vagy egy Buffer vagy stream) egy láncot ad vissza, amely rögzíti a műveleteket, és a .save(filename, callback) meghívásakor hajtja végre őket. A hasznos műveletek: resize(width, height) (megtartja az arányokat a kereten belül), thumbnail(width, height) (gyors, kis előnézet), miniature(width, height) (a képet a keretbe illeszti, a többit a háttérrel tölti ki), crop(width, height, x, y), rotate(degrees), grayscale(), blur(radius), quality(percentage) és output('jpg') a formátum átalakításához. A feltöltött fájloknál ez közvetlenül megy: a file.image() egy @upload útvonal kezelőjében ugyanezt a láncot adja vissza.
A méret olvasásához nem kell GraphicsMagick: az Image.measure('png', buffer) a PNG-, JPG-, GIF- és WebP-adatok első bájtjaiból { width, height } értéket ad vissza.
A $.image(options) olyan útvonalhoz való, amely kérésre hoz létre képet: az ext a formátum, a load(next) a forrást (streamet vagy útvonalat) adja át a next(...)-tel, az image(img) leírja a műveleteket, a cache pedig az a név, amely alatt az eredmény a tmp/ mappában marad a következő kérésekhez.
const Zlib = require('zlib');
const Fs = require('fs');
exports.install = function() {
ROUTE('GET /resize/', resize);
ROUTE('GET /thumb/', thumb);
};
// Builds a solid red PNG so that the example needs no file
function makepng(width, height) {
function chunk(type, data) {
var length = Buffer.alloc(4);
length.writeUInt32BE(data.length);
var body = Buffer.concat([Buffer.from(type), data]);
var crc = Buffer.alloc(4);
crc.writeUInt32BE(Zlib.crc32(body));
return Buffer.concat([length, body, crc]);
}
var header = Buffer.alloc(13);
header.writeUInt32BE(width, 0);
header.writeUInt32BE(height, 4);
header[8] = 8; // bit depth
header[9] = 2; // RGB
var row = Buffer.alloc(1 + width * 3);
for (var x = 0; x < width; x++)
row[1 + x * 3] = 255;
var raw = Buffer.concat(Array(height).fill(row));
return Buffer.concat([
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
chunk('IHDR', header),
chunk('IDAT', Zlib.deflateSync(raw)),
chunk('IEND', Buffer.alloc(0))
]);
}
function source() {
var filename = PATH.tmp('source.png');
Fs.writeFileSync(filename, makepng(200, 100));
return filename;
}
function resize($) {
var target = PATH.tmp('small.jpg');
Image.load(source()).resize(50, 50).output('jpg').save(target, function(err) {
if (err) {
$.invalid(err);
return;
}
var size = Image.measure('jpg', Fs.readFileSync(target));
$.json({ width: size.width, height: size.height, original: Image.measure('png', Fs.readFileSync(source())) });
});
}
function thumb($) {
$.image({
ext: 'png',
cache: 'thumb-example',
load: function(next) {
next(Fs.createReadStream(source()));
},
image: function(img) {
img.resize(40, 40);
}
});
}