2015-11-11 68 views
3

我有一些限制,我不會指定要求我將ImageMagick用作子進程。將2個stdin參數傳遞給ImageMagick child_process

我有多個base64字符串的jpg文件,我希望ImageMagick處理。 具體而言,我希望ImageMagick一起加入jpg文件。如果我有2個普通的jpg文件,然後從命令行我會使用以下格式。

node convert in_1.jpg in_2.jpg +append out.jpg 
在js文件

我會用

var spawn, magicCommands, imagic; 
spawn = require('child_process').spawn; 
magicCommands = ["in_1.jpg", 
       "in_2.jpg", 
       "+append", 
       "out.jpg"]; 
imagic = spawn("convert", magicCommands); 

現在,如果我想用標準輸入緩衝區以下將工作

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 

到目前爲止好,但我想要使用這兩個的緩衝區,而不僅僅是它們的。所以如果我用行替換那麼我該如何改變腳本的其餘部分才能使其工作?

感謝

+1

得幾許,但也許你可以使用'FE:'在ImageMagick中添加一個緩衝區,並將一個緩衝區放在'fd:3'上,另一個放在'fd:4'上... http://www.imagemagick.org/Usage/files/#fd –

+0

如果你已經有一個base64字符串這是<5000個字符),方式不[直接作爲參數傳遞](http://www.imagemagick.org/Usage/files /#inline)w /'inline:data:image/jpeg; base64,...'? – emcconville

+0

@emcconville我試圖做同樣的事情自己,但它似乎沒有工作了,我想Kurt的例子在這裏... http://stackoverflow.com/a/12067952/2836621和下** * ASIDE的例子*這裏... http://www.imagemagick.org/Usage/files/#inline這一切似乎都在IM v6.9.2-5中破碎。 –

回答

1

不能確定什麼這些「限制」是,或者我們要設法避免或解決的,但數據流將多個文件合併成一個的下列技術可幫助您:

# 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 

enter image description here

另外,如果你改變上面下面的最後一個命令,IM將盡快刪除該文件multi.miff,因爲它已經完成了它 - 即爲您整理!

convert ephemeral:multi.miff +append result.png 
+0

再次感謝,我所指的限制是我不能使用本地(基於C++)的節點模塊,因此排除了使用lwip或其他可能的選項。我真正想要的是避免不必要的寫入硬盤。緩衝區已經存在,所以如果我可以將它們作爲參數傳遞,它會比將它們保存爲文件然後刪除文件更好。如果有這樣的事情,我會發布另一個關於獲得緩衝區fd的方法! – Trevor

+1

好吧,我越來越接近理解我認爲...你有沒有考慮過臨時文件的小RAMdisk? –

+0

不是,它是一個客戶端系統,用於多次安裝。我可能會訴諸創建和刪除文件。但我會先創建緩衝流,我認爲他們可以通過他們的fd來引用,我認爲他們有。我在這裏發佈了一篇文章http://www.imagemagick.org/discourse-server/viewtopic.php?t=13100,但不明白答案 – Trevor

3

正如馬克·瑟特查在評論中指出,使用ImageMagick的fd:協議會工作。

var spawnOptions = { 
     stdio: [ 
     0, // stdin, 
     1, // stdout 
     2, // stderr 
     'pipe', // arrowBuffer1 
     'pipe' // arrowBuffer2 
     ] 
}; 
magic = spawn("convert", magicCommands, spawnOptions); 

這將打開fd:3 & fd:4的管道。我並非是家族的失敗者,但除了之外,通常還有一種方法可以傳遞資源。

爲您的代碼

更新magickCommands變量從新fd的讀取,並直接寫入新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(); 
+0

我收到一條消息imagic.stdio [3]是未定義的,我不能寫入它。我認爲儘管這一點正在接近 – Trevor