2017-08-09 44 views
0

我然後使用pixelmatch對它們進行比較,併產生第三圖像下載2個PNG圖像從它們各自的網址。上傳生成PNG到Amazon S3從節點上的λ

然後我試圖第三圖像上傳到S3桶,但我掙扎。代碼如下。

promise1promise2是分別獲得png1png2的兩個調用。下面使用的dimensions1陣列創建於promise1PNGpngjs包。

const promArr = [promise1, promise2]; 

Promise.all(promArr).then(() => { 
    const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); 
    const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); 
    const size = dimensions1[0] * dimensions1[1]; 
    diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`)); 
    const percentage = ((pix/size) * 100); 

    const fileBuffer = fs.readFileSync(`/tmp/${targetHash}.png`); 

    const s3 = new AWS.S3(); 
    s3.putObject({ 
    ACL: 'public-read', 
    Key: targetFilename, 
    Body: fileBuffer, 
    Bucket: targetBucket, 
    ContentType: 'image/png', 
    }, (err) => { 
    if (err) { 
     console.warn(err); 
     cb(err); 
    } else { 
     cb(null, { 
     percentage, 
     hash: `${targetFilename}`, 
     key: `${targetFilename}`, 
     bucket: targetBucket, 
     url: `${event.stageVariables.endpoint}${targetFilename}`, 
     }); 
    } 
    return; 
    }); 
}) 
.catch((err) => { 
    console.warn(`error: ${err}`); 
    cb(err); 
}); 

這會返回一個指向mac上預覽報告爲空的圖像的URL。這表明我有一個異步問題。

我也試圖通過diff.pack()作爲身體和得到了錯誤:Cannot determine length of [object Object]。我找到了關於這個錯誤here的討論。

我感到很接近解決方案,但我不是很到達那裏。誰能幫忙?謝謝

+0

您是否檢查過在S3存儲桶上授予的權限?與Lambda函數關聯的IAM角色應具有寫入訪問權限,以便能夠寫入存儲桶。請參閱[文檔](http://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role)。 – Olli

+0

@olli感謝您的評論!我使用無服務器來設置IAM規則。這裏是我的陽明的一部分: 'iamRoleStatements: - 大意是: 「允許」 行動: - 「S3:ListBucket」 - 「S3:將*」 - 「S3:GetObject的」 資源: - 「ARN :AWS:S3 ::: $ {自我:custom.bucket_name}」 - 「ARN:AWS:S3 ::: $ {自我:custom.bucket_name}/*」' 我需要的東西,以及投入寫? 編輯:我試圖讓格式行爲,但不能破解它:/ –

回答

0

請參閱下面的解決方案。這是一個異步問題。從here拿來筆記。 一旦管道創建臨時文件已經完成s3的東西開始。注意使用的是提到here的createReadStream。

const promArr = [promise1, promise2]; 

Promise.all(promArr).then(() => { 
    const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); 
    const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); 
    const size = dimensions1[0] * dimensions1[1]; 
    const percentage = ((pix/size) * 100); 

    diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`).on('finish',() => { 
    const fileBuffer = fs.createReadStream(`/tmp/${targetHash}.png`); 

    const s3 = new AWS.S3(); 
    s3.putObject({ 
     ACL: 'public-read', 
     Key: targetFilename, 
     Body: fileBuffer, 
     Bucket: targetBucket, 
     ContentType: 'image/png', 
    }, (err) => { 
     if (err) { 
     console.warn(err); 
     cb(err); 
     } else { 
     cb(null, { 
      percentage, 
      hash: `${targetFilename}`, 
      key: `${targetFilename}`, 
      bucket: targetBucket, 
      url: `${event.stageVariables.endpoint}${targetFilename}`, 
     }); 
     } 
     return; 
    }); 
    })); 
}) 
.catch((err) => { 
    console.warn(`error: ${err}`); 
    cb(err); 
}); 

我不是寫TMP的則回讀出一次,但它似乎是與AWS-SDK限制處理,現在最簡單的方法完全滿意。