ForgeTotal.js 5
el

Total.js 5

Αλλαγή μεγέθους και μετατροπή εικόνων

Total.js 5 · total5@0.0.19 imagesthumbnailsgraphicsmagick Εκτελέστηκε με το Total.js 5

Το Total.js επεξεργάζεται εικόνες καλώντας το GraphicsMagick (gm) ή το ImageMagick, που πρέπει να είναι εγκατεστημένα στον διακομιστή (brew install graphicsmagick, apt install graphicsmagick). Η ρύθμιση $imageconverter επιλέγει το πρόγραμμα: gm (προεπιλογή), im ή magick.

Το Image.load(filename) (ή ένα Buffer ή ένα stream) επιστρέφει μια αλυσίδα που καταγράφει τις λειτουργίες και τις εκτελεί όταν καλέσετε το .save(filename, callback). Οι χρήσιμες λειτουργίες είναι resize(width, height) (διατηρεί τις αναλογίες μέσα στο πλαίσιο), thumbnail(width, height) (μια γρήγορη, μικρή προεπισκόπηση), miniature(width, height) (χωράει την εικόνα στο πλαίσιο και γεμίζει το υπόλοιπο με το φόντο), crop(width, height, x, y), rotate(degrees), grayscale(), blur(radius), quality(percentage) και output('jpg') για μετατροπή της μορφής. Με τα αρχεία που ανεβάζονται γίνεται απευθείας: το file.image() σε έναν χειριστή διαδρομών @upload επιστρέφει την ίδια αλυσίδα.

Για να διαβάσετε το μέγεθος δεν χρειάζεται GraphicsMagick: το Image.measure('png', buffer) επιστρέφει { width, height } από τα πρώτα bytes δεδομένων PNG, JPG, GIF και WebP.

Το $.image(options) προορίζεται για μια διαδρομή που δημιουργεί μια εικόνα κατά απαίτηση: το ext είναι η μορφή, το load(next) παραδίδει την πηγή (ένα stream ή μια διαδρομή) με το next(...), το image(img) περιγράφει τις λειτουργίες και το cache είναι ένα όνομα με το οποίο το αποτέλεσμα φυλάσσεται στο tmp/ για τα επόμενα αιτήματα.

controllers/images.js
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);
		}
	});
}