Stitch multiple pngs with Jimp - node.js

I need to stitch multiple pngs into a long png, and I believe I can use Jimp's blit method:
// blit the image with another Jimp image at x, y, optionally cropped.
image.blit( src, x, y, [srcx, srcy, srcw, srch] );
My question is, how do I loop along all the pngs and make the current png attach to the end of the previous one? For example, they are all in a same folder with file names like img-1, img-2 ... img-10. And their sizes are not necessarily the same. This is what I have in mind, any suggestions would be greatly appreciated!
// This is dummy code
const bg = white_background
bg.width = Math.max(img-1...img-10 width)
bg.height = sum(img-1...img-10 height)
for (let i=0;i<imgs.length;i++) {
if(i=0) bg.blit(img, 0, 0)
else bg.blit(img, imgs[i-1].width, imgs[i-1].height)
}

Related

Can fabric.js parse raster graphic to "real" svg?

I have a question/problem with fabric.js - in my code the user can upload a picture, with filters he can convert it to a black/white image. When I export the picture with canvas.toSVG(); it exports a svg image, but it is no real vector graphic - it loses quality when scaling up.
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
var imgInstance = new fabric.Image(img, {
scaleX: 0.7,
scaleY: 0.7
})
canvas.add(imgInstance);
}
img.src = event.target.result;
} reader.readAsDataURL(e.target.files[0]);}
$('saveBtn').onclick = function() {
var filedata= canvas.toSVG(); // the SVG file is now in filedata
var locfile = new Blob([filedata], {type: "image/svg+xml;charset=utf-8"});
var locfilesrc = URL.createObjectURL(locfile);//mylocfile);
var dwn = document.getElementById('dwn');
dwn.innerHTML = "<a href=" + locfilesrc + " download='mysvg.svg'>Download</a>";}
What am I doing wrong?
There is no easy way to "parse" raster graphics to a vector image. Vector graphics include information for how to draw an image, while raster images only include the pixel data for how an image appears at a given size and resolution. That's enough for many purposes, but it means that while it's easy to go from vector to raster (just execute the instructions), it's not easy to go from raster to vector.
It is possible to "trace" the edges of a raster image to obtain vectors that can approximate the raster: in other words, a set of vector instructions that, for that particular resolution and depth, yields an image that is the same as the original raster (or something very like it). But there is no guarantee that these actually correspond in any way to the original vectors (if there are any original vectors at all). Usually there is no correspondence, in fact, unless your tracing algorithm is very specialized: for example, tracing images of a font to make a vector copy of that font. Because they don't correspond, there's no guarantee that the image will scale up the way you want it to: it'll scale, but things may enlarge in strange ways.
It is possible to implement tracing algorithms in JavaScript, by drawing the image into a <canvas> element, using getImageData() to grab the pixel information from that, and performing your operations on the pixel information. Doing this, though, is beyond the scope of this question.

Poor quality jpeg resize on GD library use. Wrong steps?

So I have the following script to resize an incoming jpg and save it to the server in a new size. The created jpg file has terrible quality, even when I am making the quality 90 on the imagejpeg. I am wondering if I am messing it up earlier in my efforts.
// Get new sizes
list($width, $height) = getimagesize($filename);
$percentW=298/$width;
$newwidth = $width * $percentW;
$newheight = $height * $percentW;
// Creating a blank canvas to put the new file. Is this an extra step?
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($filename);
// Now I create the resized photo with the needed width and height on the blank canvas with the source file resized
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Output to server, define 90% quality. My guess is the quality is destroyed before now.
imagejpeg($thumb,"../../uploads/buckets/" . $_POST["bucket"] . "/" .$fileNameBucket,90);
imagedestroy($thumb);
Am I messing up the quality before I even output the file to the server? Should I use resample instead of resize? I am stuck with using the GD library so ImageMagick is not an option. Thanks.

view RGBA image

Can someone tell me how can I view an RGBA image? I just want a tool that I can display an RGBA image with!
I have written a code, which outputs only RGBA format. I just want to verify if my code worked, and just want to find a simple tool to view this image.
I wasn't able to come across a software to be able to display a RGBA image.
Thanks in advance.
RGBA files only contain raw channel data. The binary data will not have enough information to display an image (ie. width,height,depth, &tc).
If you know the image dimensions of each .rgba file, you should be able to work with the data. Here's an example of viewing raw date in javascript.
var fr = new FileReader(),
myWidth = 200,
myHeight = 200;
fr.onload = function(frEvent) {
var canvasElement = document.getElementById("myCanvas"),
ctx = canvasElement.getContext("2d"),
blob = ctx.createImageData(myWidth,myHeight),
index = 0;
while(index < frEvent.target.result.length)
blob.data[index] = frEvent.target.result.charCodeAt(index++);
ctx.putImageData(blob,0,0);
}
Imagemagick will be able to display raw RGBA data. Assuming that each color sample is 8 bits.
display -size 200x200 -depth 8 mySimpleData.rgba

Save an array of pixels to a file

In the Haxe programming language, is there any cross-language way to save an array of pixel data to a file (e. g., in BMP or PNG format)?
class SavePixelsToFile {
static function main(){
//how can I save this array of pixel data to a file? It is a simple 2D array of RGB arrays, with the red, green, and blue components in the respective order.
var arr = [
[[0, 0, 0],[255, 255, 255]],
[[255, 255, 255],[0, 0, 0]]
];
}
}
The format library will do what you want. http://code.google.com/p/hxformat/
Install this library: haxelib install format
Link it in your hxml file using: -lib format
To write image data to a file, do the following:
function writePixels24(file:String, pixels:haxe.io.Bytes, width:Int, height:Int) {
var handle = sys.io.File.write(file, true);
new format.png.Writer(handle)
.write(format.png.Tools.build24(width, height, pixels));
handle.close();
}
var bo = new haxe.io.BytesOutput();
for (pixel in pixels)
for (channel in pixel)
bo.writeByte(channel);
var bytes = bo.getBytes();
writePixels24("Somefile.png", bytes);
This will work for targets that have the sys.* package (Not flash). you can still generate the png without the sys.* package, but will need an alternate method of saving the file.
An easy to write format is PPM. The netpbm tools can easily manipulate those and also convert to many formats including PBM and PNG.

How to create a `pixelized' SVG image from a bitmap?

I have a 16x16 bitmap and want to create an SVG that contains 16x16 squares with the colors of the pixels of the image. Is there an easy way to achieve this?
My current thoughts go into the direction of using Python and PIL to read the bitmap image and dynamically create an SVG image file with the corresponding objects. But this feels a little clumsy and like reinventing the wheel.
Is there a better way to do this?
If you don't need the output to be SVG, I would suggest using an HTML5 Canvas where you can sample the pixels of the image client-side (using getImageData() on the context) and then draw your own up-scaled image. Or, if you need SVG, you could still use Canvas for the image sampling and then use procedurally-created <rect/> elements in SVG for each pixel.
I've written an example using just HTML Canvas so you can see how to do this. In short:
function drawPixelated(img,context,zoom,x,y){
if (!zoom) zoom=4; if (!x) x=0; if (!y) y=0;
if (!img.id) img.id = "__img"+(drawPixelated.lastImageId++);
var idata = drawPixelated.idataById[img.id];
if (!idata){
var ctx = document.createElement('canvas').getContext('2d');
ctx.width = img.width;
ctx.height = img.height;
ctx.drawImage(img,0,0);
idata = drawPixelated.idataById[img.id] = ctx.getImageData(0,0,img.width,img.height).data;
}
for (var x2=0;x2<img.width;++x2){
for (var y2=0;y2<img.height;++y2){
var i=(y2*img.width+x2)*4;
var r=idata[i ];
var g=idata[i+1];
var b=idata[i+2];
var a=idata[i+3];
context.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
context.fillRect(x+x2*zoom, y+y2*zoom, zoom, zoom);
}
}
};
drawPixelated.idataById={};
drawPixelated.lastImageId=0;
If you really need SVG involved, I'd be happy to write an example that dynamically generated that.
Edit: OK, I've created an SVG version just for fun and practice. :)
As an aside (from an initial misreading of your question) this demo file from ASVG3 their old SVG Examples Page shows how to use some complex compositing of many different effects to create pixelation on arbitrary vector data. Unfortunately the demo does not load in Chrome, having been hardwired to require the (now-discontinued) Adobe SVG Viewer.

Resources