Skip to content

Commit

Permalink
sample retina images support
Browse files Browse the repository at this point in the history
Added "text" support for placeholder backend method.
Added "placeholder2" method that uses a bigger font and 2x stripes
Added "coverx" and "resizex" methods that do cover/resize manipulation but only to reduce image sizes (while cover and resize also enlarge to the requested size).
Added content type to manipulated images.
Added sample retina-plugin to editor.html to show how to rewrite placeholderText, placeholderUrl, convertedUrl to make mosaico use 2x images.
(I guess this can be a fix for #531)
  • Loading branch information
bago committed Nov 4, 2022
1 parent 492fbd9 commit 3189d42
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
47 changes: 31 additions & 16 deletions backend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ var font;
Jimp.loadFont(Jimp.FONT_SANS_32_BLACK, function(err, f) {
font = f;
});
var font2x;
Jimp.loadFont(Jimp.FONT_SANS_64_BLACK, function(err, f) {
font2x = f;
});

app.use(require('connect-livereload')({ ignore: [/^\/dl/, /^\/img/, /^\/upload/] }));

Expand Down Expand Up @@ -98,19 +102,20 @@ app.get('/img/', function(req, res) {

var params = req.query.params.split(',');

if (req.query.method == 'placeholder') {
var size = 40;
if (req.query.method == 'placeholder' || req.query.method == 'placeholder2') {
var size = req.query.method == 'placeholder2' ? 80 : 40;
var w = parseInt(params[0]);
var h = parseInt(params[1]);
var text = req.query.text ? req.query.text : '' + w + ' x ' + h;
var workScale = 1;

new Jimp(w * workScale, h * workScale, '#808080', function(err, image) {
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) {
if ((((Math.ceil(image.bitmap.height / (size * workScale * 2))+1)*(size * workScale * 2) + x - y) % (size * workScale * 2)) < size * workScale) image.setPixelColor(0x707070FF, x, y);
if (x == image.bitmap.width - 1 && y == image.bitmap.height - 1) {
var tempImg = new Jimp(w * workScale, h * workScale, 0x0)
.print(font, 0, 0, {
text: '' + w + ' x ' + h,
.print(req.query.method == 'placeholder2' ? font2x : font, 0, 0, {
text: text,
alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER,
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
}, w * workScale, h * workScale)
Expand All @@ -124,15 +129,15 @@ app.get('/img/', function(req, res) {
if (error) {
console.log("Error #2 creating placeholder: ", error);
res.status(500).send('Error #1 creating placeholder: ' + err.message);
} else res.status(200).send(new Buffer(buffer));
} else res.status(200).contentType('image/png').send(new Buffer(buffer));
});
}
});
}
});
});

} else if (req.query.method == 'resize' || req.query.method == 'cover' || req.query.method == 'aspect') {
} else if (req.query.method == 'resize' || req.query.method == 'resizex' || req.query.method == 'cover' || req.query.method == 'coverx' || req.query.method == 'aspect') {
// NOTE: req.query.src is an URL: we do parse it to localpath.
var urlparsed = url.parse(req.query.src);
var src = "./"+decodeURI(urlparsed.pathname);
Expand Down Expand Up @@ -166,17 +171,21 @@ app.get('/img/', function(req, res) {
if (error) {
console.log("Error sending manipulated image: ", error);
res.status(500).send('Unexpected condition manipulating image: ' + error.message);
} else res.status(200).send(new Buffer(buffer));
} else res.status(200).contentType('image/png').send(new Buffer(buffer));
});
}
};
if (req.query.method == 'resize') {
if (params[0] == 'null')
image.resize(Jimp.AUTO, parseInt(params[1]), sendOrError);
else if (params[1] == 'null')
image.resize(parseInt(params[0]), Jimp.AUTO, sendOrError);
else
image.contain(parseInt(params[0]), parseInt(params[1]), sendOrError);
if (req.query.method == 'resize' || req.query.method == 'resizex') {
if (params[0] == 'null') {
if (req.query.method == 'resize' || image.bitmap.height > parseInt(params[1])) image.resize(Jimp.AUTO, parseInt(params[1]), sendOrError);
else sendOrError(false, image);
} else if (params[1] == 'null') {
if (req.query.method == 'resize' || image.bitmap.width > parseInt(params[0])) image.resize(parseInt(params[0]), Jimp.AUTO, sendOrError);
else sendOrError(false, image);
} else {
if (req.query.method == 'resize' || image.bitmap.width > parseInt(params[0]) || image.bitmap.height > parseInt(params[1])) image.contain(parseInt(params[0]), parseInt(params[1]), sendOrError);
else sendOrError(false, image);
}
} else {
// Compute crop coordinates for cover algorythm
var w = parseInt(params[0]);
Expand All @@ -186,11 +195,17 @@ app.get('/img/', function(req, res) {
if (ar > origAr) {
var newH = Math.round(image.bitmap.width / ar);
var newY = Math.round((image.bitmap.height - newH) / 2);
image.crop(0, newY, image.bitmap.width, newH).resize(w, h, sendOrError);
image.crop(0, newY, image.bitmap.width, newH);
// coverx does not enlarge cropped images
if (req.query.method == 'cover' || newH > h) image.resize(w, h, sendOrError);
else sendOrError(false, image);
} else {
var newW = Math.round(image.bitmap.height * ar);
var newX = Math.round((image.bitmap.width - newW) / 2);
image.crop(newX, 0, newW, image.bitmap.height).resize(w, h, sendOrError);
image.crop(newX, 0, newW, image.bitmap.height);
// coverx does not enlarge cropped images
if (req.query.method == 'cover' || newW > w) image.resize(w, h, sendOrError);
else sendOrError(false, image);
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/html/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@
var plugins;
// A basic plugin that expose the "viewModel" object as a global variable.
// plugins = [function(vm) {window.viewModel = vm;}];
// An example of a retina plugin (2x images), using custom manipulation function (resizex and coverx instead of resize and cover)
/*
plugins = [function(vm) {
// overrides placeholder text
ko.bindingHandlers.wysiwygSrc.placeholderText = function(w, h) {
return w && h ? w+'x'+h : w ? '<'+w+'>' : 'h'+h;
};
// double width and height for placeholder call and call method=placeholder2 so to have larger stripes
var origPlaceholderUrl = ko.bindingHandlers.wysiwygSrc.placeholderUrl;
ko.bindingHandlers.wysiwygSrc.placeholderUrl = function(w, h, text, method) {
return origPlaceholderUrl(w*2, h*2, text, 'placeholder2');
};
// double width and height and call coverx/resizex instead of cover/resize so to avoid enlarging images
var origConvertedUrl = ko.bindingHandlers.wysiwygSrc.convertedUrl;
ko.bindingHandlers.wysiwygSrc.convertedUrl = function(src, method, width, height) {
return origConvertedUrl(src, method+'x', width ? width*2 : width, height ? height*2 : height);
};
}];
*/
var ok = Mosaico.init({
imgProcessorBackend: basePath+'/img/',
emailProcessorBackend: basePath+'/dl/',
Expand Down

0 comments on commit 3189d42

Please sign in to comment.