Why Spatie/Image package compresses the image even when only manipulating dimensions? - laravel

Take a look at this script:
$path = 'storage/test-image.JPG';
$savePath = 'storage/test-image-saved.JPG';
$image = \Spatie\Image\Image::load(public_path($path));
$image
->height($image->getHeight()) // manipulating height to its original height
->save(public_path($savePath));
$originalSize = File::size(public_path($path)); // 1.7MB
$savedSize = File::size(public_path($savePath)); // 200KB
The result is that the image got compressed, and its colour changed. This is out of my expectation for an image manipulation tool.
Can anyone with experience care to explain it a bit?
Thank you.

Related

dotted output after skeletonization in matlab

I wish to skeletonize this image
To do so i am using matlab's bwmorph function, Here is the snippet :
bw = bwmorph(img_bw,'skel',Inf);
However the output is not as expected. Here is the output.
Could someone suggest a better way to achieve proper results ?
EDIT: here is a stripped down relevant code
img = imread(name);
img = rgb2gray(img*4);
img_bw = img > 50;
img_bw = medfilt2(img_bw,[10 10]);
bw = bwmorph(img_bw,'skel',Inf);
What you see is aliasing, the imshow function can not display the full image because it is to large to fit the screen. To fit the screen some rows and columns are skipped, which cause the lines to be disconnected. To display an image at full resolution using a scrollpanel, use imscrollpanel
hFig = figure('Toolbar','none', 'Menubar','none');
hIm = imshow(bw);
hSP = imscrollpanel(hFig,hIm);

How to improve display quality in pdf.js

I'm using open source library for PDF documents from mozilla(pdf.JS).
When i'm trying to open pdf documents with bad quality, viewer displays it with VERY BAD quality.
But if I open it in reader, or in browser (drag/drop into new window), whis document displays well
Is it possible to change?
Here is this library on github mozilla pdf.js
You just have to change the scaling of your pdf i.e. when rendering a page:
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport(scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
...
It is the scale value you have to change. Then, the resulting rendered image will fit into the canvas given its dimensions e.g. in CSS. What this means is that you produce a bigger image, fit it into the container you had before and so you effectively improve the resolution.
There is renderPage function in web/viewer.js and print resolution is hard-coded in there as 150 DPI.
function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) {
var scratchCanvas = activeService.scratchCanvas;
var PRINT_RESOLUTION = 150;
var PRINT_UNITS = PRINT_RESOLUTION / 72.0;
To change print resolution to 300 DPI, simply change the line below.
var PRINT_RESOLUTION = 300;
See How to increase print quality of PDF file with PDF.js viewer for more details.
Maybe it's an issue related with pixel ratio, it used to happen to me when device pixel ratio is bigger than 1 (for example iPhone, iPad, etc.. you can read this question for a better explanation.
Just try that file on PDF.js Viewer. If it works like expected, you must check how PDF.js works with pixel ratio > 1 here. What library basically does is:
canvas.width = viewport.width * window.devicePixelRatio;
canvas.styles.width = viewport.width + 'px'; // Note: The px unit is required here
But you must check how PDF.js works for better perfomance
I ran into the same issue and I used the intent option of renderContent to fix that.
const renderContext = {
intent: 'print',
// ....
}
var renderTask = page.render(renderContext);
As per docs renderContext accepts intent which supports three values - display, print or any. The default is display. When I used print instead the render quality was extremely good, at par with any desktop app.

Reassembling a fragmented image

I have an image that has been broken in to parts, 64 rows by 64 columns. Each image is 256x256px. The images are all PNG. They are named "Image--.png" for example "Image-3-57". The rows and columns numbering start from 0 rather than 1.
How can I assemble this back in to one image? Ideally using BASH and tools (I'm a sysadmin) though PHP would be acceptable as well.
Well, it is not very complicated, if you want to use PHP. What you need is just a few image gunctions - imagecreate and imagecopy. If your PNG is semi transparent, you will also need imagefilledrectangle to create a transparent background.
In code below, I rely on fact, that all chunks are same size - so the pixel size must be able to be divided by the number of chunks.
<?php
$width = 256*64; //height of the big image, pixels
$height = 256*64;
$chunks_X = 64; //Number of chunks
$chunks_Y = 64; //Same for Y
$chuk_size_X = $width/$chunks_X; //Compute size of one chunk, will be needed in copying
$chuk_size_Y = $height/$chunks_Y;
$big = imagecreate($width, $height); //Create the big one
for($y=0; $y<$chunks_Y; $y++) {
for($x=0; $x<chunks_X; $x++) {
$chunk = imagecreatefrompng("Image-$x-$y.png");
imagecopy($big, $chunk,
$x*$chuk_size_X, //position where to place little image
$y*$chuk_size_Y,
0, //where to copy from on little image
0,
$chuk_size_X, //size of the copyed area - whole little image here
$chuk_size_Y,
);
imagedestroy($chunk); //Don't forget to clear memory
}
}
?>
This is just a draft. I'm not sure about all theese xs and ys as well as ather details. It is late and I'm tired.

Codeigniter - Re-sizing multiple images works, but wrong sizes?

I'm trying to resize a fullsize image poster into three smaller variants of the file. I first save the fullsize poster, then i use it's path to create the smaller ones. The problem is that the sizes are incorrect. I have a $conf array containing general config info for all images, and then i have a $conf array for each image with specific changes (eg. size). I clear the lib before every new init.
// Config for all images
$conf['source_image'] = $file_path;
$conf['quality'] = 80;
$conf['maintain_ratio'] = true;
$conf['master_dim'] = 'auto';
// Small
$conf['new_image'] = 'img/movie_images/posters_small/' . $file_name;
$conf['height'] = 75;
//$conf['width'] = 55;
$this->image_lib->initialize($conf);
$this->image_lib->resize();
$this->image_lib->clear();
//unset($conf['width']);
// Medium
$conf['new_image'] = 'img/movie_images/posters_medium/' . $file_name;
$conf['height'] = 200;
$this->image_lib->initialize($conf);
$this->image_lib->resize();
$this->image_lib->clear();
// Big
$conf['new_image'] = 'img/movie_images/posters_big/' . $file_name;
$conf['height'] = 300;
$this->image_lib->initialize($conf);
$this->image_lib->resize();
$this->image_lib->clear();
See any errors in the code? I tried outputting errors as someone advised in another question here, but that didn't show anything either. I don't understand how it works really. If i set "master_dim" to auto, the first (the small) image get's the right height, but the default width (which is really really wide). If i set master_dim to "width", the small image stays the same (really wide, but correct height). If i set master_dim to "height" they all get the correct height, but the small one still is super wide.
Any ideas?
As you can see in the code i tried playing around with the width of the small image to get it's correct size, but didn't get it to work.
After setting master_dim to height, and also setting the width of the small image manually, it works as i want it to.
You can download the image library from http://thephpcode.com/blog/codeigniter/gradient-image-library-for-codeigniter to convert the image to fit in to a correct width and size.

How do I improve quality when using RMagick/ImageMagick to convert from SVG to PDF?

I use Rubyvis to generate SVG plots, and then allow the user to save either to SVG directly, or to some other format using RMagick.
The SVG plots have a set size, which is specified in the SVG file. It seems to me, then, that it should be trivial to convert to a PDF of the same size.
Unfortunately, this appears not to be the case. I can produce a PDF in this manner, but it is much larger (dimension-wise) than the PDFs produced if I first open the SVG in inkscape and then print-to-file as a PDF.
Worse, the PDF image quality is terrible.
Am I missing some instruction for Magick? Here's the code:
image = Magick::Image::from_blob(svg_string_data) { self.format = 'SVG' }
image[0].format = 'PDF'
image[0].to_blob
I then write the value returned (the PDF blob) directly into a file.
The answer comes to you based on a tip from cptjazz on github.
First of all, the documentation for RMagick is often wrong. I doubt this is a version problem, because the ImageMagick-hosted docs are v2.12.0, and I'm using v2.13.1. Either way, here is what you need to know.
The docs claim you can use image[0]['pdf', 'use-cropbox'] = true, since true.to_s yields the String 'true'. In fact, it needs an explicit string, and the []= method takes only one key, not two.
I did not experiment with pdf:use-trimbox, mainly because I wanted an option that also works for postscript. For postscript, you should be able to amend it only slightly, and set ps:use-cropbox to 'true', but RMagick's docs are unclear as to how one may properly set the geometry on a PS, PS2, or PS3. (Normally in ImageMagick, one would set the density to '300x300' and the geometry to '24%', supposedly.) And for some reason, PS3-format output files do not scale as well as the PDFs produced by RMagick. But I digress.
Here is what I used for PDF:
image = Magick::Image::from_blob(svg_string) { self.format = 'SVG' }
image[0].format = 'PDF'
image[0]["use-cropbox"] = 'true'
image[0].to_blob
And here is what I used for PS:
image = Magick::Image::from_blob(svg_string) { self.format = 'SVG' }
page = image[0].page.dup
image[0]["use-cropbox"] = 'true'
image[0].format = 'PS3'
image[0].density = '100x100'
image[0].page = page
image[0].to_blob
For some reason, setting a higher density makes the image smaller. Why that should be is a mystery.

Resources