问题
I have certain limitations that I won't specify that require me to use ImageMagick as a child-process.
I have multiple base 64 strings of jpg files which I want ImageMagick to process. Specifically I want ImageMagick to join the jpg files together. If I had 2 regular jpg files then from the command line I would use the following format.
node convert in_1.jpg in_2.jpg +append out.jpg
in a js file I would use
var spawn, magicCommands, imagic;
spawn = require('child_process').spawn;
magicCommands = ["in_1.jpg",
"in_2.jpg",
"+append",
"out.jpg"];
imagic = spawn("convert", magicCommands);
Now if I wanted to use 1 stdin buffer the following would work
var arrow1JpgBase64, arrow2JpgBase64, arrowBuffer1, arrowBuffer2, magicCommands, imagic;
spawn = require('child_process').spawn;
exec = require('child_process').exec;
arrow1JpgBase64 = "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAFAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD1/wCFngjxJba78QbWT4reLTLH4pZ2mjt9PLTCSxs5VL+bbSYZUkWPCFUxGu1EHFdz/wAIb4j/AOiseM//AAF0n/5BoooA/9k=";
arrow2JpgBase64 = "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAFAAkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD1/wCOvgjxJc/Dt7NPit4tMt1q+k20Ty2+nqsLyajbIkoMFtFJuRmDjbIpyo5xmu5/4Q3xH/0Vjxn/AOAuk/8AyDRRQB//2Q==";
arrowBuffer1 = new Buffer(arrow1JpgBase64, 'base64');
arrowBuffer2 = new Buffer(arrow2JpgBase64, 'base64');
magicCommands = ["jpg:",
"in_2.jpg",
"+append",
"out.jpg"];
imagic = spawn("convert", magicCommands);
imagic.stdin.write(arrowBuffer1);
imagic.stdin.end();
imagic.on('exit', function (code) {
if (code === 0) {
exec("open out.jpg");
} else {
console.log("error code: " + code);
}
}); // end of on exit
So far so good, but I want to use both of the buffers and not just 1 of them. So if I replace the "in_2.jpg",
line with "jpg:",
then how do I have to change the rest of the script to get it to work?
Thanks
回答1:
As Mark Setchell pointed out in the comments, using ImageMagick's fd:
protocol will work.
var spawnOptions = {
stdio: [
0, // stdin,
1, // stdout
2, // stderr
'pipe', // arrowBuffer1
'pipe' // arrowBuffer2
]
};
magic = spawn("convert", magicCommands, spawnOptions);
This opens fd:3
& fd:4
for piping. I'm not failure with the node.js family, but there usually a way to pass a resource in addition to pipe.
For your code
Update the magickCommands
variable to read from new fd
's, and write directly to new pipes
magicCommands = ["fd:3",
"fd:4",
"+append",
"out.jpg"];
// ...
imagic.stdio[3].write(arrowBuffer1);
imagic.stdio[4].write(arrowBuffer2);
imagic.stdio[3].end();
imagic.stdio[4].end();
回答2:
Not really sure what these "limitations" are, or what we are trying to avoid or work around, but the following technique of streaming multiple files into one may help you:
# Make a red block
convert -size 50x50 xc:red multi.miff
# Make a green block, but APPEND INTO A SINGLE STREAM
convert -size 50x50 xc:lime miff:- >> multi.miff
# Make a blue block, but APPEND INTO A SINGLE STREAM
convert -size 50x50 xc:blue miff:- >> multi.miff
# Tell IM to convert and append multiple images in single stream
convert multi.miff +append result.png
Also, if you change the last command above to the following, IM will delete the file multi.miff
as soon as it has finished with it - i.e. tidy up for you!
convert ephemeral:multi.miff +append result.png
来源:https://stackoverflow.com/questions/33655680/passing-2-stdin-arguments-to-a-imagemagick-child-process