123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- ;(function(jsPDFAPI) {
- 'use strict'
- var namespace = 'addImage_'
- var getJpegSize = function(imgData) {
- 'use strict'
- var width, height;
-
- if (!imgData.charCodeAt(0) === 0xff ||
- !imgData.charCodeAt(1) === 0xd8 ||
- !imgData.charCodeAt(2) === 0xff ||
- !imgData.charCodeAt(3) === 0xe0 ||
- !imgData.charCodeAt(6) === 'J'.charCodeAt(0) ||
- !imgData.charCodeAt(7) === 'F'.charCodeAt(0) ||
- !imgData.charCodeAt(8) === 'I'.charCodeAt(0) ||
- !imgData.charCodeAt(9) === 'F'.charCodeAt(0) ||
- !imgData.charCodeAt(10) === 0x00) {
- throw new Error('getJpegSize requires a binary jpeg file')
- }
- var blockLength = imgData.charCodeAt(4)*256 + imgData.charCodeAt(5);
- var i = 4, len = imgData.length;
- while ( i < len ) {
- i += blockLength;
- if (imgData.charCodeAt(i) !== 0xff) {
- throw new Error('getJpegSize could not find the size of the image');
- }
- if (imgData.charCodeAt(i+1) === 0xc0 ||
- imgData.charCodeAt(i+1) === 0xc1 ||
- imgData.charCodeAt(i+1) === 0xc2 ||
- imgData.charCodeAt(i+1) === 0xc3 ||
- imgData.charCodeAt(i+1) === 0xc4 ||
- imgData.charCodeAt(i+1) === 0xc5 ||
- imgData.charCodeAt(i+1) === 0xc6 ||
- imgData.charCodeAt(i+1) === 0xc7) {
- height = imgData.charCodeAt(i+5)*256 + imgData.charCodeAt(i+6);
- width = imgData.charCodeAt(i+7)*256 + imgData.charCodeAt(i+8);
- return [width, height];
- } else {
- i += 2;
- blockLength = imgData.charCodeAt(i)*256 + imgData.charCodeAt(i+1)
- }
- }
- }
- , putImage = function(img) {
- var objectNumber = this.internal.newObject()
- , out = this.internal.write
- , putStream = this.internal.putStream
- img['n'] = objectNumber
- out('<</Type /XObject')
- out('/Subtype /Image')
- out('/Width ' + img['w'])
- out('/Height ' + img['h'])
- if (img['cs'] === 'Indexed') {
- out('/ColorSpace [/Indexed /DeviceRGB '
- + (img['pal'].length / 3 - 1) + ' ' + (objectNumber + 1)
- + ' 0 R]');
- } else {
- out('/ColorSpace /' + img['cs']);
- if (img['cs'] === 'DeviceCMYK') {
- out('/Decode [1 0 1 0 1 0 1 0]');
- }
- }
- out('/BitsPerComponent ' + img['bpc']);
- if ('f' in img) {
- out('/Filter /' + img['f']);
- }
- if ('dp' in img) {
- out('/DecodeParms <<' + img['dp'] + '>>');
- }
- if ('trns' in img && img['trns'].constructor == Array) {
- var trns = '';
- for ( var i = 0; i < img['trns'].length; i++) {
- trns += (img[trns][i] + ' ' + img['trns'][i] + ' ');
- out('/Mask [' + trns + ']');
- }
- }
- if ('smask' in img) {
- out('/SMask ' + (objectNumber + 1) + ' 0 R');
- }
- out('/Length ' + img['data'].length + '>>');
- putStream(img['data']);
- out('endobj');
- }
- , putResourcesCallback = function() {
- var images = this.internal.collections[namespace + 'images']
- for ( var i in images ) {
- putImage.call(this, images[i])
- }
- }
- , putXObjectsDictCallback = function(){
- var images = this.internal.collections[namespace + 'images']
- , out = this.internal.write
- , image
- for (var i in images) {
- image = images[i]
- out(
- '/I' + image['i']
- , image['n']
- , '0'
- , 'R'
- )
- }
- }
- jsPDFAPI.addImage = function(imageData, format, x, y, w, h) {
- 'use strict'
- if (typeof imageData === 'object' && imageData.nodeType === 1) {
- var canvas = document.createElement('canvas');
- canvas.width = imageData.clientWidth;
- canvas.height = imageData.clientHeight;
- var ctx = canvas.getContext('2d');
- if (!ctx) {
- throw ('addImage requires canvas to be supported by browser.');
- }
- ctx.drawImage(imageData, 0, 0, canvas.width, canvas.height);
- imageData = canvas.toDataURL('image/jpeg');
- format = "JPEG";
- }
- if (format.toUpperCase() !== 'JPEG') {
- throw new Error('addImage currently only supports format \'JPEG\', not \''+format+'\'');
- }
- var imageIndex
- , images = this.internal.collections[namespace + 'images']
- , coord = this.internal.getCoordinateString
- , vcoord = this.internal.getVerticalCoordinateString;
-
- if (imageData.substring(0, 23) === 'data:image/jpeg;base64,') {
- imageData = atob(imageData.replace('data:image/jpeg;base64,', ''));
- }
- if (images){
-
- imageIndex = Object.keys ?
- Object.keys(images).length :
- (function(o){
- var i = 0
- for (var e in o){if(o.hasOwnProperty(e)){ i++ }}
- return i
- })(images)
- } else {
-
- imageIndex = 0
- this.internal.collections[namespace + 'images'] = images = {}
- this.internal.events.subscribe('putResources', putResourcesCallback)
- this.internal.events.subscribe('putXobjectDict', putXObjectsDictCallback)
- }
- var dims = getJpegSize(imageData);
- var info = {
- w : dims[0],
- h : dims[1],
- cs : 'DeviceRGB',
- bpc : 8,
- f : 'DCTDecode',
- i : imageIndex,
- data : imageData
-
- };
- images[imageIndex] = info
- if (!w && !h) {
- w = -96;
- h = -96;
- }
- if (w < 0) {
- w = (-1) * info['w'] * 72 / w / this.internal.scaleFactor;
- }
- if (h < 0) {
- h = (-1) * info['h'] * 72 / h / this.internal.scaleFactor;
- }
- if (w === 0) {
- w = h * info['w'] / info['h'];
- }
- if (h === 0) {
- h = w * info['h'] / info['w'];
- }
- this.internal.write(
- 'q'
- , coord(w)
- , '0 0'
- , coord(h)
- , coord(x)
- , vcoord(y + h)
- , 'cm /I'+info['i']
- , 'Do Q'
- )
- return this
- }
- })(jsPDF.API)
|