2017-04-05 4 views
4

Firebase 용 클라우드 기능에는 업로드 된 각 이미지에 대해 축소판을 만드는 멋진 샘플이 있습니다. 이것은 ImageMagick을 사용하여 수행됩니다.Firebase 용 클라우드 기능 - PDF를 이미지로 변환

샘플을 변환하여 이미지를 PDF로 변환하려고했습니다. 이것은 ImageMagick이 할 수있는 일이지만 Firebase 용 Cloud Functions로는 작동하지 않습니다. 코드 1 오류가 계속 발생합니다.

ChildProcessError: `convert /tmp/cd9d0278-16b2-42be-aa3d-45b5adf89332.pdf[0] -density 200 /tmp/cd9d0278-16b2-42be-aa3d-45b5adf89332.pdf` failed with code 1 
    at ChildProcess.<anonymous> (/user_code/node_modules/child-process-promise/lib/index.js:132:23) 
    at emitTwo (events.js:106:13) 
    at ChildProcess.emit (events.js:191:7) 
    at maybeClose (internal/child_process.js:877:16) 
    at Socket.<anonymous> (internal/child_process.js:334:11) 
    at emitOne (events.js:96:13) 
    at Socket.emit (events.js:188:7) 
    at Pipe._handle.close [as _onclose] (net.js:498:12) 

물론 PDF 변환은 지원되지 않습니다.

const functions = require('firebase-functions'); 
const gcs = require('@google-cloud/storage')(); 
const spawn = require('child-process-promise').spawn; 
// [END import] 

// [START generateThumbnail] 
/** 
* When an image is uploaded in the Storage bucket We generate a thumbnail automatically using 
* ImageMagick. 
*/ 
// [START generateThumbnailTrigger] 
exports.generateThumbnail = functions.storage.object().onChange(event => { 
// [END generateThumbnailTrigger] 
    // [START eventAttributes] 
    const object = event.data; // The Storage object. 

    const fileBucket = object.bucket; // The Storage bucket that contains the file. 
    const filePath = object.name; // File path in the bucket. 
    const contentType = object.contentType; // File content type. 
    const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions). 
    // [END eventAttributes] 

    // [START stopConditions] 
    // Exit if this is triggered on a file that is not an image. 
    if (!contentType.startsWith('application/pdf')) { 
     console.log('This is not a pdf.'); 
     return; 
    } 

    // Get the file name. 
    const fileName = filePath.split('/').pop(); 
    // Exit if the image is already a thumbnail. 
    if (fileName.startsWith('thumb_')) { 
     console.log('Already a Thumbnail.'); 
     return; 
    } 

    // Exit if this is a move or deletion event. 
    if (resourceState === 'not_exists') { 
     console.log('This is a deletion event.'); 
     return; 
    } 
    // [END stopConditions] 

    // [START thumbnailGeneration] 
    // Download file from bucket. 
    const bucket = gcs.bucket(fileBucket); 
    const tempFilePath = `/tmp/${fileName}`; 
    return bucket.file(filePath).download({ 
     destination: tempFilePath 
    }).then(() => { 
     console.log('Pdf downloaded locally to', tempFilePath); 
     // Generate a thumbnail of the first page using ImageMagick. 
     return spawn('convert', [tempFilePath+'[0]' ,'-density', '200', tempFilePath]).then(() => { 
      console.log('Thumbnail created at', tempFilePath); 
      // Convert pdf extension to png 
      const thumbFilePath = filePath.replace('.pdf', 'png'); 
      // Uploading the thumbnail. 
      return bucket.upload(tempFilePath, { 
       destination: thumbFilePath 
      }); 
     }); 
    }); 
    // [END thumbnailGeneration] 
}); 
+0

pdf 파일을 변환하는 경우 Google Cloud 기능에 기본적으로 설치되지 않은 ghostscript 패키지가 필요합니다. – EJay

+0

다른 방법이 있습니까? 안타깝게도 이것이 이용 가능하지 않습니다 ... –

+1

아직 발견되지 않았습니다. 최소한 firebase에 클라우드 기능을 사용하지 마십시오. – EJay

답변

1

노드 모듈은 Cloud 기능의 소스 코드와 동일한 디렉토리에있는 원시 코드를 설치할 수 있습니다. 내가 발견 PDF 처리를위한 매우 유용한 라이브러리 고스트에 대해이 작업을 수행 GitHub의에 대한 몇 가지 노드 라이브러리 :

후 내 패키지 파일에 종속성으로 node-gs 추가 다음과 같이하십시오 :

{ 
    "name": "functions", 
    "dependencies": { 
    "@google-cloud/storage": "^1.3.1", 
    "child-process-promise": "^2.2.1", 
    "firebase-admin": "~5.4.0", 
    "firebase-functions": "^0.7.2", 
    "gs": "https://github.com/sina-masnadi/node-gs/tarball/master" 
    } 
} 

내 index.js 파일에서 노드 라이브러리에서 JavaScript의 고스트 스크립트를 쉽게 사용할 수 있습니다. 여기

const functions = require('firebase-functions'); 
const gcs = require('@google-cloud/storage')(); 
const spawn = require('child-process-promise').spawn; 
const path = require('path'); 
const os = require('os'); 
const fs = require('fs'); 
var gs = require('gs'); 

exports.makePNG = functions.storage.object().onChange(event => { 

    // ignore delete events 
    if (event.data.resourceState == 'not_exists') return false; 

    const filePath = event.data.name; 
    const fileDir = path.dirname(filePath); 
    const fileName = path.basename(filePath); 
    const tempFilePath = path.join(os.tmpdir(), fileName); 
    if (fileName.endsWith('.png')) return false; 
    if (!fileName.endsWith('.pdf')) return false; 

    const newName = path.basename(filePath, '.pdf') + '.png'; 
    const tempNewPath = path.join(os.tmpdir(), newName); 


    // // Download file from bucket. 
    const bucket = gcs.bucket(event.data.bucket); 

    return bucket.file(filePath).download({ 
    destination: tempFilePath 
    }).then(() => { 
    console.log('Image downloaded locally to', tempFilePath); 

    return new Promise(function (resolve, reject) { 
     gs() 
      .batch() 
      .nopause() 
      .option('-r' + 50 * 2) 
      .option('-dDownScaleFactor=2') 
      .executablePath('lambda-ghostscript/bin/./gs') 
      .device('png16m') 
      .output(tempNewPath) 
      .input(tempFilePath) 
      .exec(function (err, stdout, stderr) { 
       if (!err) { 
       console.log('gs executed w/o error');    
       console.log('stdout',stdout);    
       console.log('stderr',stderr);    
       resolve(); 
       } else { 
       console.log('gs error:', err); 
       reject(err); 
       } 
      }); 
    }); 

    }).then(() => { 
    console.log('PNG created at', tempNewPath); 

    // Uploading the thumbnail. 
    return bucket.upload(tempNewPath, {destination: newName}); 
    // Once the thumbnail has been uploaded delete the local file to free up disk space. 
    }).then(() => { 
    fs.unlinkSync(tempNewPath); 
    fs.unlinkSync(tempFilePath); 
    }).catch((err) => { 
    console.log('exception:', err); 
    return err; 
    }); 

}); 

GitHub의에서 프로젝트는 다음과 같습니다 : 다음은 Google 클라우드 스토리지 트리거를 사용하는 클라우드 기능에 대한 전체 코드는 https://github.com/ultrasaurus/ghostscript-cloud-function

면책 조항 :이 컴파일 된 네이티브 코드를 사용하여 내가이 작동 실험적 검증 그래서 괜찮을거야. 특정 컴파일 옵션을 살펴 보지 않고 클라우드 기능 환경을 정확하게 수정했는지 확인했습니다.

관련 문제