SlideShare uma empresa Scribd logo
1 de 26
Baixar para ler offline
그래픽 및 

HTML5 비디오
PDF 생성 및 다루기
❖ 자식 프로세스 - PDF Toolkit, wkhtmltopdf!
❖ 모듈 - PDFKit
자식 프로세스 - wkhtmltopdf
❖ wkhtmltopdf - WebKit 렌더링 엔진을 사용해서 

HTML을 PDF 로 변환.!
❖ wkthmltopdf http://mindpreview.com
test.pdf
Ex12-1
var spawn = require('child_process').spawn;!
// command line arguments!
var url = process.argv[2]; !
var output = process.argv[3];!
if (url && output) {!
! var wkhtmltopdf = spawn('wkhtmltopdf', [url, output]);!
! wkhtmltopdf.stdout.setEncoding('utf8'); !
! wkhtmltopdf.stdout.on('data', function (data) {!
! ! console.log(data); !
! });!
! wkhtmltopdf.stderr.on('data', function (data) {!
! ! console.log('stderr: ' + data); !
! });!
! wkhtmltopdf.on('exit', function (code) {!
! ! console.log('child process exited with code ' + code); !
! });!
} else {!
! console.log('You need to provide a URL and output file name'); !
}
PDFToolkit으로PDF접근
Dump Number of Pages
var spawn = require('child_process').spawn;!
var pdftk = spawn('pdftk', [__dirname + '/test.pdf', 'dump_data']);!
!
pdftk.stdout.on('data', function (data) {!
! // convert results to an object!
! var array = data.toString().split('n'); !
! var obj = {};!
! array.forEach(function(line) { !
! ! var tmp = line.split(':'); !
! ! obj[tmp[0]] = tmp[1];!
! });!
! // print out number of pages!
! console.log(obj['NumberOfPages']); !
});!
!
pdftk.stderr.on('data', function (data) {!
! console.log('stderr: ' + data); !
});!
!
pdftk.on('exit', function (code) {!
! console.log('child process exited with code ' + code); !
});
PDF 업로드 및 

그래픽 대기 시간 처리
❖ PDF 업로드!
❖ PDF 저장!
❖ PDF 페이지 분할!
❖ email 통보!
❖ PDF 페이지 링크 및 개별 페이지
업로드 폼
<form id="upload" method="POST" action="http://localhost:8124"
enctype="multipart/form-data">!
<p><label for="username">User Name:</label>!
<input id="username" name="username" type="text" size="20" required /></p>!
!
<p><label for="email">Email:</label>!
<input id="email" name="email" type="text" size="20" required /></p>!
!
<p><label for="pdffile">PDF File:</label>!
<input type="file" name="pdffile" id="pdffile" required /></p>!
<p>!
<p>!
!
<input type="submit" name="submit" id="submit" value="Submit"/> !
</p>!
</form>
업로드 처리
var connect = require('connect');!
var pdfprocess = require('./pdfprocess');!
// if POST!
// upload file, kick off PDF burst, respond with ack !
function upload(req, res, next){!
! if ('POST' != req.method) return next();!
!
! res.setHeader('Content-Type', 'text/html');!
! if (req.files.pdffile && req.files.pdffile.type === 'application/pdf') {!
! ! res.write('<p>Thanks ' + req.body.username +!
! ! ! ! ' for uploading ' + req.files.pdffile.name + '</p>');!
! ! res.end("<p>You'll receive an email with file links when processed.</p>");!
! ! // post upload processing !
! ! pdfprocess.processFile(req.body.username, req.body.email, !
! ! ! req.files.pdffile.path, req.files.pdffile.name);!
! }else {!
! ! res.end('The file you uploaded was not a PDF');!
! }!
}
PDF 처리
//burst pdf!
var pdftk = spawn('pdftk', [newfile, 'burst', 'output', dir + '/page_%02d.pdf' ]);!
pdftk.on('exit', function (code) { !
! console.log('child process ended with ' + code); !
! if (code != 0)!
! ! return;!
! console.log('sending email'); // send email!
! ! ! ! ! !
! var server = emailjs.server.connect(!
! ! ! { user : 'gmail.account.name', !
! ! ! password : 'gmail.account.passwod', !
! ! ! host : 'smtp.gmail.com', port : 587, tls : true }!
! );!
! var headers = {!
! ! text : 'You can find your split PDF at ' + url, from : 'youremail',!
! ! to : email,!
! ! subject: 'split pdf'!
! };!
! ! ! ! !
! var message = emailjs.message.create(headers); !
! message.attach(!
! ! {data:"<p>You can find your split PDF at " +!
! ! "<a href='" + url + "'>" + url + "</a></p>", alternative: true}!
! );!
! server.send(message, function(err, message) {!
! ! console.log(err || message); !
! });!
! ! ! ! ! !
! pdftk.kill(); !
});
PDFKit 으로 PDF 생성
❖ PDF 문서 생성, 페이지 추가, 

텍스트와 그래픽 넣기, 이미지 내장…!
❖ npm install pdfkit
PDFKit
PDFDocument = require ('pdfkit')!
var fs = require('fs');!
!
var doc = new PDFDocument();!
!
doc.pipe(fs.createWriteStream('output.pdf'));!
!
doc.font('/Library/Fonts/Arial.ttf')!
! .fontSize(25)!
! .text('Some text with an embedded font!', 100, 100);!
!
doc.addPage()!
! .fontSize(25)!
! .text('Here is some vector graphics...', 100, 100);!
!
doc.save()!
! .moveTo(100, 150)!
! .lineTo(100, 250)!
! .lineTo(200, 250)!
! .fill("#FF3300");!
!
doc.scale(0.6)!
! .translate(470, -380)!
! .path('M 250,75 L 323,301 131,161 369,161 171,301 z')!
! .fill('red', 'even-odd')!
! .restore();!
!
doc.addPage()!
! .fillColor("blue")!
! .text('Here is a link!', 100, 100) !
! .underline(100, 100, 160, 27, {color: "#0000FF"}) !
! .link(100, 100, 160, 27, 'http://google.com/');!
!
doc.end();
ImageMagick
❖ ImageMagick 은 명령줄 그래픽 도구.!
❖ 이미지를 자르거나 크기 조정, 메타 데이터 접근, 

애니메이션 생성, 특수 효과 …!
❖ 리소스를 많이 사용, 작업에 따라 많은 시간 소요.!
❖ npm install imagemagick
ImageMagick 기능
❖ convert - 자르기, 크기 조절, 효과 추가등 변환 작업.!
❖ mogrify - 이미지를 수정해서 현재 이미지에 저장.!
❖ montage - 여러 이미지로부터 합성 이미지를 생성.!
❖ stream - 한 픽셀씩 저장소에 이미지를 스트리밍.
$ convert NatGeo01.jpg -resize ‘150’ photo.jpg.png
var spawn = require('child_process').spawn;!
// get photo!
var photo = process.argv[2];!
// conversion array !
var opts = [!
! photo,!
! '-resize',!
! '150',!
! photo + ".png"];!
! !
// convert!
var im = spawn('convert', opts);!
!
im.stderr.on('data', function (data) { !
! console.log('stderr: ' + data);!
});!
!
im.on('exit', function (code) { !
! if (code === 0)!
! ! console.log('photo has been converted and is accessible at ' +
photo + '.png');!
});
Polaroid effect
❖ convert NatGeo03.jpg 

-bordercolor white -border 6 

-bordercolor grey60 -border 1 

-background none -rotate 6 

-background black ( +clone -shadow 60x4+4+4 )
+swap  -background none -flatten 

polaroid.png
var spawn = require('child_process').spawn;!
// get photo!
var photo = process.argv[2];!
// conversion array!
var opts = [!
photo,!
"-bordercolor", "snow",!
"-border", "6",!
"-background","grey60",!
"-background", "none",!
"-rotate", "6",!
"-background", "black",!
"(", "+clone", "-shadow", "60x4+4+4", ")", !
"+swap",!
"-background", "none", !
"-flatten",!
photo + ".png"];!
!
var im = spawn('convert', opts);
명령줄 도구 처리 시간
❖ 동시 사용자가 많거나, 수행 시간이 긴 경우,!
❖ 모든 작업 완료를 대기하지 말고,!
❖ 완료후 링크(사이트, 이메일)을 주는 기능 제공.
HTML 5 비디오 (범위지원)
❖ 응답 헤더에 Accept-Ranges: bytes 추가.!
❖ 요청 헤더에 범위 요청 찾기/파싱.

bytes=startnum-endnum!
❖ 범위 검사/재설정.!
❖ 응답 헤더에 Content-Range, Content-Length 추가.!
❖ 응답 헤더 상태 코드를 206 또는 416 으로 설정.!
❖ 범위에 맞게 데이터 전송.
Mini server
function processRange(res,ranges,len) { !
! var start, end;!
! // extract start and stop range!
! var rangearray = ranges.split('-');!
! start = parseInt(rangearray[0].substr(6)); !
! end = parseInt(rangearray[1]);!
! !
! if (isNaN(start)) !
! ! start = 0; !
! if (isNaN(end)) !
! ! end = len − 1;!
! // start beyond end of file length !
! if (start > len - 1) {!
! ! res.setHeader('Content-Range', 'bytes */' + len); !
! ! res.writeHead(416);!
! ! res.end();!
! }!
! // end can't be beyond file length if (end > len - 1)!
! end = len - 1;!
! return {start:start, end:end}; !
}
http.createServer(function (req, res) {!
! pathname = __dirname + '/public' + req.url;!
! fs.stat(pathname, function(err, stats) { !
! ! if (stats.isFile()) {!
! ! ! var opt={};!
! ! ! res.statusCode = 200;!
! ! ! var len = stats.size;!
! ! ! // we have a Range request !
! ! ! if (req.headers.range) {!
! ! ! ! opt = processRange(res,req.headers.range,len);!
! ! ! ! // adjust length!
! ! ! ! len = opt.end - opt.start + 1;!
! ! ! ! // change status code to partial!
! ! ! ! res.statusCode = 206;!
! ! ! ! // set header!
! ! ! ! var ctstr = 'bytes ' + opt.start + '-' +!
! ! ! ! opt.end + '/' + stats.size;!
! ! ! ! res.setHeader('Content-Range', ctstr); !
! ! ! }!
!
! ! ! console.log('len ' + len); !
! ! ! res.setHeader('Content-Length', len);!
!
! ! ! // create and pipe readable stream!
! ! ! var file = fs.createReadStream(pathname,opt); !
! ! ! file.on("open", function() {!
! ! ! ! file.pipe(res); !
! ! ! });!
! ! } !
! });!
}).listen(8124);
Canvas 컨텐츠 생성 및 스트리밍
❖ canvas 요소는 클라이언트 웹 페이지에서 동적이고 인터
랙티브한 그래픽을 제공.!
❖ npm install canvas!
❖ Canvas 개체와 컨텍스트를 생성/그리기 후, 

결과를 jpeg/png 파일로 저장할 수 있음.
Canvas Drawing
var Canvas = require('canvas'); !
var fs = require('fs');!
// new canvas and context!
var canvas = new Canvas(350,350); !
var ctx = canvas.getContext('2d');!
// create filled rectangle with shadow !
// save context for later restore !
ctx.save();!
ctx.shadowOffsetX = 10; !
ctx.shadowOffsetY = 10;!
ctx.shadowBlur = 5; !
ctx.shadowColor='rgba(0,0,0,0.4)';!
!
ctx.fillStyle = '#fff';!
ctx.fillRect(30,30,300,300);
ctx.translate(125,125);!
for (i=1;i<6;i++){!
! ctx.save();!
! ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)'; !
! for (j=0;j<i*6;j++){!
! ! ctx.rotate(Math.PI*2/(i*6));!
! ! ctx.beginPath(); !
! ! ctx.arc(0,i*12.5,5,0,Math.PI*2,true);!
! ! ctx.fill();!
! }!
! ctx.restore();!
}!
// stream to PNG file!
var out = fs.createWriteStream(__dirname + '/shadow.png'); !
var stream = canvas.createPNGStream();!
stream.on('data', function(chunk){ !
! out.write(chunk);!
});!
stream.on('end', function(){ !
! console.log('saved png');!
});

Mais conteúdo relacionado

Mais de Kyungryul KIM

전문검색기술도전
전문검색기술도전전문검색기술도전
전문검색기술도전Kyungryul KIM
 
Nib_NSWindowController
Nib_NSWindowControllerNib_NSWindowController
Nib_NSWindowControllerKyungryul KIM
 
서버인프라를지탱하는기술5 1 2
서버인프라를지탱하는기술5 1 2서버인프라를지탱하는기술5 1 2
서버인프라를지탱하는기술5 1 2Kyungryul KIM
 
Chaper24 languages high_and_low
Chaper24 languages high_and_lowChaper24 languages high_and_low
Chaper24 languages high_and_lowKyungryul KIM
 
Ch22 운영체제
Ch22 운영체제Ch22 운영체제
Ch22 운영체제Kyungryul KIM
 
DDD-07-Using The Language
DDD-07-Using The LanguageDDD-07-Using The Language
DDD-07-Using The LanguageKyungryul KIM
 
Cleancode ch16 serialdate_refactoring
Cleancode ch16 serialdate_refactoringCleancode ch16 serialdate_refactoring
Cleancode ch16 serialdate_refactoringKyungryul KIM
 

Mais de Kyungryul KIM (20)

Ch4 pugixml
Ch4 pugixmlCh4 pugixml
Ch4 pugixml
 
Cocos2 d x-7.3_4
Cocos2 d x-7.3_4Cocos2 d x-7.3_4
Cocos2 d x-7.3_4
 
Cocos2d x-ch5-1
Cocos2d x-ch5-1Cocos2d x-ch5-1
Cocos2d x-ch5-1
 
Coco2d x
Coco2d xCoco2d x
Coco2d x
 
23 drag drop
23 drag drop23 drag drop
23 drag drop
 
Hadoop ch5
Hadoop ch5Hadoop ch5
Hadoop ch5
 
전문검색기술도전
전문검색기술도전전문검색기술도전
전문검색기술도전
 
Nib_NSWindowController
Nib_NSWindowControllerNib_NSWindowController
Nib_NSWindowController
 
Dsas
DsasDsas
Dsas
 
서버인프라를지탱하는기술5 1 2
서버인프라를지탱하는기술5 1 2서버인프라를지탱하는기술5 1 2
서버인프라를지탱하는기술5 1 2
 
Chaper24 languages high_and_low
Chaper24 languages high_and_lowChaper24 languages high_and_low
Chaper24 languages high_and_low
 
Ch22 운영체제
Ch22 운영체제Ch22 운영체제
Ch22 운영체제
 
Mibis ch20
Mibis ch20Mibis ch20
Mibis ch20
 
Mibis ch15
Mibis ch15Mibis ch15
Mibis ch15
 
Mibis ch8
Mibis ch8Mibis ch8
Mibis ch8
 
Mibis ch4
Mibis ch4Mibis ch4
Mibis ch4
 
14 strategy design
14 strategy design14 strategy design
14 strategy design
 
Ddd ch12-13
Ddd ch12-13Ddd ch12-13
Ddd ch12-13
 
DDD-07-Using The Language
DDD-07-Using The LanguageDDD-07-Using The Language
DDD-07-Using The Language
 
Cleancode ch16 serialdate_refactoring
Cleancode ch16 serialdate_refactoringCleancode ch16 serialdate_refactoring
Cleancode ch16 serialdate_refactoring
 

Node ch12

  • 2. PDF 생성 및 다루기 ❖ 자식 프로세스 - PDF Toolkit, wkhtmltopdf! ❖ 모듈 - PDFKit
  • 3. 자식 프로세스 - wkhtmltopdf ❖ wkhtmltopdf - WebKit 렌더링 엔진을 사용해서 
 HTML을 PDF 로 변환.! ❖ wkthmltopdf http://mindpreview.com test.pdf
  • 4. Ex12-1 var spawn = require('child_process').spawn;! // command line arguments! var url = process.argv[2]; ! var output = process.argv[3];! if (url && output) {! ! var wkhtmltopdf = spawn('wkhtmltopdf', [url, output]);! ! wkhtmltopdf.stdout.setEncoding('utf8'); ! ! wkhtmltopdf.stdout.on('data', function (data) {! ! ! console.log(data); ! ! });! ! wkhtmltopdf.stderr.on('data', function (data) {! ! ! console.log('stderr: ' + data); ! ! });! ! wkhtmltopdf.on('exit', function (code) {! ! ! console.log('child process exited with code ' + code); ! ! });! } else {! ! console.log('You need to provide a URL and output file name'); ! }
  • 6. Dump Number of Pages var spawn = require('child_process').spawn;! var pdftk = spawn('pdftk', [__dirname + '/test.pdf', 'dump_data']);! ! pdftk.stdout.on('data', function (data) {! ! // convert results to an object! ! var array = data.toString().split('n'); ! ! var obj = {};! ! array.forEach(function(line) { ! ! ! var tmp = line.split(':'); ! ! ! obj[tmp[0]] = tmp[1];! ! });! ! // print out number of pages! ! console.log(obj['NumberOfPages']); ! });! ! pdftk.stderr.on('data', function (data) {! ! console.log('stderr: ' + data); ! });! ! pdftk.on('exit', function (code) {! ! console.log('child process exited with code ' + code); ! });
  • 7. PDF 업로드 및 
 그래픽 대기 시간 처리 ❖ PDF 업로드! ❖ PDF 저장! ❖ PDF 페이지 분할! ❖ email 통보! ❖ PDF 페이지 링크 및 개별 페이지
  • 8. 업로드 폼 <form id="upload" method="POST" action="http://localhost:8124" enctype="multipart/form-data">! <p><label for="username">User Name:</label>! <input id="username" name="username" type="text" size="20" required /></p>! ! <p><label for="email">Email:</label>! <input id="email" name="email" type="text" size="20" required /></p>! ! <p><label for="pdffile">PDF File:</label>! <input type="file" name="pdffile" id="pdffile" required /></p>! <p>! <p>! ! <input type="submit" name="submit" id="submit" value="Submit"/> ! </p>! </form>
  • 9. 업로드 처리 var connect = require('connect');! var pdfprocess = require('./pdfprocess');! // if POST! // upload file, kick off PDF burst, respond with ack ! function upload(req, res, next){! ! if ('POST' != req.method) return next();! ! ! res.setHeader('Content-Type', 'text/html');! ! if (req.files.pdffile && req.files.pdffile.type === 'application/pdf') {! ! ! res.write('<p>Thanks ' + req.body.username +! ! ! ! ! ' for uploading ' + req.files.pdffile.name + '</p>');! ! ! res.end("<p>You'll receive an email with file links when processed.</p>");! ! ! // post upload processing ! ! ! pdfprocess.processFile(req.body.username, req.body.email, ! ! ! ! req.files.pdffile.path, req.files.pdffile.name);! ! }else {! ! ! res.end('The file you uploaded was not a PDF');! ! }! }
  • 10. PDF 처리 //burst pdf! var pdftk = spawn('pdftk', [newfile, 'burst', 'output', dir + '/page_%02d.pdf' ]);! pdftk.on('exit', function (code) { ! ! console.log('child process ended with ' + code); ! ! if (code != 0)! ! ! return;! ! console.log('sending email'); // send email! ! ! ! ! ! ! ! var server = emailjs.server.connect(! ! ! ! { user : 'gmail.account.name', ! ! ! ! password : 'gmail.account.passwod', ! ! ! ! host : 'smtp.gmail.com', port : 587, tls : true }! ! );! ! var headers = {! ! ! text : 'You can find your split PDF at ' + url, from : 'youremail',! ! ! to : email,! ! ! subject: 'split pdf'! ! };! ! ! ! ! ! ! var message = emailjs.message.create(headers); ! ! message.attach(! ! ! {data:"<p>You can find your split PDF at " +! ! ! "<a href='" + url + "'>" + url + "</a></p>", alternative: true}! ! );! ! server.send(message, function(err, message) {! ! ! console.log(err || message); ! ! });! ! ! ! ! ! ! ! pdftk.kill(); ! });
  • 11. PDFKit 으로 PDF 생성 ❖ PDF 문서 생성, 페이지 추가, 
 텍스트와 그래픽 넣기, 이미지 내장…! ❖ npm install pdfkit
  • 12. PDFKit PDFDocument = require ('pdfkit')! var fs = require('fs');! ! var doc = new PDFDocument();! ! doc.pipe(fs.createWriteStream('output.pdf'));! ! doc.font('/Library/Fonts/Arial.ttf')! ! .fontSize(25)! ! .text('Some text with an embedded font!', 100, 100);! ! doc.addPage()! ! .fontSize(25)! ! .text('Here is some vector graphics...', 100, 100);! ! doc.save()! ! .moveTo(100, 150)! ! .lineTo(100, 250)! ! .lineTo(200, 250)! ! .fill("#FF3300");! ! doc.scale(0.6)! ! .translate(470, -380)! ! .path('M 250,75 L 323,301 131,161 369,161 171,301 z')! ! .fill('red', 'even-odd')! ! .restore();! ! doc.addPage()! ! .fillColor("blue")! ! .text('Here is a link!', 100, 100) ! ! .underline(100, 100, 160, 27, {color: "#0000FF"}) ! ! .link(100, 100, 160, 27, 'http://google.com/');! ! doc.end();
  • 13. ImageMagick ❖ ImageMagick 은 명령줄 그래픽 도구.! ❖ 이미지를 자르거나 크기 조정, 메타 데이터 접근, 
 애니메이션 생성, 특수 효과 …! ❖ 리소스를 많이 사용, 작업에 따라 많은 시간 소요.! ❖ npm install imagemagick
  • 14. ImageMagick 기능 ❖ convert - 자르기, 크기 조절, 효과 추가등 변환 작업.! ❖ mogrify - 이미지를 수정해서 현재 이미지에 저장.! ❖ montage - 여러 이미지로부터 합성 이미지를 생성.! ❖ stream - 한 픽셀씩 저장소에 이미지를 스트리밍.
  • 15. $ convert NatGeo01.jpg -resize ‘150’ photo.jpg.png
  • 16. var spawn = require('child_process').spawn;! // get photo! var photo = process.argv[2];! // conversion array ! var opts = [! ! photo,! ! '-resize',! ! '150',! ! photo + ".png"];! ! ! // convert! var im = spawn('convert', opts);! ! im.stderr.on('data', function (data) { ! ! console.log('stderr: ' + data);! });! ! im.on('exit', function (code) { ! ! if (code === 0)! ! ! console.log('photo has been converted and is accessible at ' + photo + '.png');! });
  • 17. Polaroid effect ❖ convert NatGeo03.jpg 
 -bordercolor white -border 6 
 -bordercolor grey60 -border 1 
 -background none -rotate 6 
 -background black ( +clone -shadow 60x4+4+4 ) +swap -background none -flatten 
 polaroid.png
  • 18.
  • 19. var spawn = require('child_process').spawn;! // get photo! var photo = process.argv[2];! // conversion array! var opts = [! photo,! "-bordercolor", "snow",! "-border", "6",! "-background","grey60",! "-background", "none",! "-rotate", "6",! "-background", "black",! "(", "+clone", "-shadow", "60x4+4+4", ")", ! "+swap",! "-background", "none", ! "-flatten",! photo + ".png"];! ! var im = spawn('convert', opts);
  • 20. 명령줄 도구 처리 시간 ❖ 동시 사용자가 많거나, 수행 시간이 긴 경우,! ❖ 모든 작업 완료를 대기하지 말고,! ❖ 완료후 링크(사이트, 이메일)을 주는 기능 제공.
  • 21. HTML 5 비디오 (범위지원) ❖ 응답 헤더에 Accept-Ranges: bytes 추가.! ❖ 요청 헤더에 범위 요청 찾기/파싱.
 bytes=startnum-endnum! ❖ 범위 검사/재설정.! ❖ 응답 헤더에 Content-Range, Content-Length 추가.! ❖ 응답 헤더 상태 코드를 206 또는 416 으로 설정.! ❖ 범위에 맞게 데이터 전송.
  • 22. Mini server function processRange(res,ranges,len) { ! ! var start, end;! ! // extract start and stop range! ! var rangearray = ranges.split('-');! ! start = parseInt(rangearray[0].substr(6)); ! ! end = parseInt(rangearray[1]);! ! ! ! if (isNaN(start)) ! ! ! start = 0; ! ! if (isNaN(end)) ! ! ! end = len − 1;! ! // start beyond end of file length ! ! if (start > len - 1) {! ! ! res.setHeader('Content-Range', 'bytes */' + len); ! ! ! res.writeHead(416);! ! ! res.end();! ! }! ! // end can't be beyond file length if (end > len - 1)! ! end = len - 1;! ! return {start:start, end:end}; ! }
  • 23. http.createServer(function (req, res) {! ! pathname = __dirname + '/public' + req.url;! ! fs.stat(pathname, function(err, stats) { ! ! ! if (stats.isFile()) {! ! ! ! var opt={};! ! ! ! res.statusCode = 200;! ! ! ! var len = stats.size;! ! ! ! // we have a Range request ! ! ! ! if (req.headers.range) {! ! ! ! ! opt = processRange(res,req.headers.range,len);! ! ! ! ! // adjust length! ! ! ! ! len = opt.end - opt.start + 1;! ! ! ! ! // change status code to partial! ! ! ! ! res.statusCode = 206;! ! ! ! ! // set header! ! ! ! ! var ctstr = 'bytes ' + opt.start + '-' +! ! ! ! ! opt.end + '/' + stats.size;! ! ! ! ! res.setHeader('Content-Range', ctstr); ! ! ! ! }! ! ! ! ! console.log('len ' + len); ! ! ! ! res.setHeader('Content-Length', len);! ! ! ! ! // create and pipe readable stream! ! ! ! var file = fs.createReadStream(pathname,opt); ! ! ! ! file.on("open", function() {! ! ! ! ! file.pipe(res); ! ! ! ! });! ! ! } ! ! });! }).listen(8124);
  • 24. Canvas 컨텐츠 생성 및 스트리밍 ❖ canvas 요소는 클라이언트 웹 페이지에서 동적이고 인터 랙티브한 그래픽을 제공.! ❖ npm install canvas! ❖ Canvas 개체와 컨텍스트를 생성/그리기 후, 
 결과를 jpeg/png 파일로 저장할 수 있음.
  • 25. Canvas Drawing var Canvas = require('canvas'); ! var fs = require('fs');! // new canvas and context! var canvas = new Canvas(350,350); ! var ctx = canvas.getContext('2d');! // create filled rectangle with shadow ! // save context for later restore ! ctx.save();! ctx.shadowOffsetX = 10; ! ctx.shadowOffsetY = 10;! ctx.shadowBlur = 5; ! ctx.shadowColor='rgba(0,0,0,0.4)';! ! ctx.fillStyle = '#fff';! ctx.fillRect(30,30,300,300);
  • 26. ctx.translate(125,125);! for (i=1;i<6;i++){! ! ctx.save();! ! ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)'; ! ! for (j=0;j<i*6;j++){! ! ! ctx.rotate(Math.PI*2/(i*6));! ! ! ctx.beginPath(); ! ! ! ctx.arc(0,i*12.5,5,0,Math.PI*2,true);! ! ! ctx.fill();! ! }! ! ctx.restore();! }! // stream to PNG file! var out = fs.createWriteStream(__dirname + '/shadow.png'); ! var stream = canvas.createPNGStream();! stream.on('data', function(chunk){ ! ! out.write(chunk);! });! stream.on('end', function(){ ! ! console.log('saved png');! });