get dpi and set quality by specific size
Hi Joseph, its seems good, yet i have to try this. can you implement or suggest to achive with html 5 canvas api
-- how to get the image dpi eg: 300 pixels or 96 so we can . -- how can we resize image by specify image weight size., as uploaded image of x size and we want to reduce image at spefic jpeg quality 90 or 30 , but still image weight is higher than requirement, so if we can get what quality param we can get specific image weight size
ex: upload image : 5mb set weight : 200kb get quality param: 10 %
resize( jpeg_quality ) get resize image of what weight we wanted
Hello there!
To get the image DPI, you can access the EXIF data via the getEXIF() method call, and examine the XResolution and YResolution properties. Example:
{
"Make": "Apple",
"Model": "iPhone 7",
"Orientation": 1,
"XResolution": 72,
"YResolution": 72,
"ResolutionUnit": 2,
"Software": "10.3.1",
"DateTime": "2017:04:29 16:36:23",
...
}
This example image is 72x72 API. Note that only some images provide this EXIF data, so have a default fallback (72 DPI is typical). Please call this function immediately after loading the image, as most transforms wipe the EXIF data (because they clone and copy/paste the canvas).
For saving images based on a target file size, there is no provided way using the node-canvas library (on the server) or HTML5 Canvas API (on the client). They only allow you to specify the JPEG quality as a percentage number (1 - 100).
The only way I can think to accomplish this is to do a brute-force method. Meaning, save at 50%, measure size, increase or decrease by 25%, measure size, then 12.5%, etc. then either add half or subtract half, and repeat until you get close to your target size. To prevent an infinite loop, only allow 8 iterations or so. Quick example:
var fs = require('fs');
var async = require('async');
var CanvasPlus = require('canvas-plus');
var canvas = new CanvasPlus();
canvas.load('test.jpg', function(err) {
if (err) throw err;
var target_size = 50 * 1024; // 50KB target
var idx = 0;
var max_iterations = 8;
var current_quality = 50;
var current_size = 0;
var current_buffer = null;
var adjust_by = 25;
async.doWhilst(
function(callback) {
// test a save, record size
canvas.write({format: "jpeg", quality: Math.floor(current_quality)}, function(err, buf) {
idx++;
current_buffer = buf;
console.log( current_quality + '% Quality: ' + buf.length + ' bytes' );
if (buf.length < target_size) {
current_quality += adjust_by;
adjust_by /= 2;
}
else if (buf.length > target_size) {
current_quality -= adjust_by;
adjust_by /= 2;
}
else {
idx = max_iterations;
}
if (current_quality < 1) current_quality = 1;
callback();
});
},
function() {
return( idx < max_iterations );
},
function(err) {
console.log("\nFinal image: " + current_buffer.length + " bytes (" + canvas.get('quality') + "% quality)");
fs.writeFileSync( 'myimage.jpg', current_buffer );
}
); // doWhilst
});
This works on my test image (target: 50K):
50% Quality: 44309 bytes
75% Quality: 67193 bytes
62.5% Quality: 52631 bytes
56.25% Quality: 47946 bytes
59.375% Quality: 50268 bytes
60.9375% Quality: 50980 bytes
61.71875% Quality: 52006 bytes
61.328125% Quality: 52006 bytes
Final image: 52006 bytes (61% quality)
Good luck!