From 0e742827cbbcf7db7960df66d6faa22f567d5c5f Mon Sep 17 00:00:00 2001 From: tanaikech Date: Tue, 20 Dec 2022 14:49:16 +0900 Subject: [PATCH] Updated to v1.3.1 --- ImgApp.js | 788 +++++++++++++++++++++++++++--------------------------- README.md | 4 + 2 files changed, 394 insertions(+), 398 deletions(-) diff --git a/ImgApp.js b/ImgApp.js index c7d9564..78767a1 100644 --- a/ImgApp.js +++ b/ImgApp.js @@ -1,6 +1,5 @@ -// Generated by CoffeeScript 2.7.0 -(function() { - +// Generated by CoffeeScript 1.12.7 + /** * Title ImgApp
* Author Tanaike
@@ -67,157 +66,39 @@ function editImage(object) { return new ImgApp().EditImage(object) } ; - (function(r) { - var ImgApp; - ImgApp = (function() { - var GetImage, GetResizedSize, byte2hex, byte2hexNum, byte2num, cropImage, fetch, getFormat, getImageFromSlide, getInfBMP, getInfGIF, getInfJPG, getInfPNG, hex2num, mergeImages, pixelToEmu, pixelToPt, ptToEmu, ptToPixel; - - class ImgApp { - constructor(blob) { - this.bytear = []; - } - - // EditImage -------------------------------------------------------------------------------- - EditImage(obj_) { - if (obj_.hasOwnProperty("blob") && obj_.hasOwnProperty("crop") && obj_.blob.toString() === "Blob" && typeof obj_.crop === "object") { - return cropImage.call(this, obj_); - } else if (obj_.hasOwnProperty("merge") && Array.isArray(obj_.merge) && Array.isArray(obj_.merge[0])) { - return mergeImages.call(this, obj_); - } else { - throw new Error("Wrong object. Please confirm it again."); - } - } - - // UpdateThumbnail -------------------------------------------------------------------------------- - UpdateThumbnail(imgFileId_, srcFileId_) { - var boundary, data, fields, headers, img4thumb, metadata, method, mime, payload, url; - if (imgFileId_ == null) { - throw new Error("No image file ID."); - } - if (srcFileId_ == null) { - throw new Error("No source file ID."); - } - img4thumb = DriveApp.getFileById(imgFileId_); - mime = img4thumb.getMimeType(); - if (mime !== "image/png" && mime !== "image/gif" && mime !== "image/hpeg") { - throw new Error("The image format (" + mime + ") cannot be used for thumbnail."); - } - metadata = { - contentHints: { - thumbnail: { - image: Utilities.base64EncodeWebSafe(img4thumb.getBlob().getBytes()), - mimeType: mime - } - } - }; - fields = "id,mimeType,name,thumbnailVersion,thumbnailLink"; - url = "https://www.googleapis.com/upload/drive/v3/files/" + srcFileId_ + "?uploadType=multipart&fields=" + encodeURIComponent(fields); - boundary = "xxxxxxxxxx"; - data = "--" + boundary + "\r\n"; - data += "Content-Disposition: form-data; name=\"metadata\"\r\n"; - data += "Content-Type: application/json; charset=UTF-8\r\n\r\n"; - data += JSON.stringify(metadata) + "\r\n"; - data += "--" + boundary + "--\r\n"; - payload = Utilities.newBlob(data).getBytes(); - headers = { - "Authorization": "Bearer " + ScriptApp.getOAuthToken(), - "Content-Type": "multipart/related; boundary=" + boundary - }; - method = "patch"; - return fetch.call(this, url, method, payload, headers); - } - - // DoResize -------------------------------------------------------------------------------- - DoResize(fileId, width) { - var blob, e, headers, method, mimetype, n, res, resized, rs, thumbUrl, turl, url; - try { - url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?fields=thumbnailLink%2CmimeType"; - method = "get"; - headers = { - "Authorization": "Bearer " + ScriptApp.getOAuthToken() - }; - res = fetch.call(this, url, method, null, headers); - thumbUrl = res.thumbnailLink; - mimetype = res.mimeType; - r = thumbUrl.split("="); - } catch (error) { - e = error; - throw new Error("'" + fileId + "' is not compatible file. Error message is " + JSON.stringify(e)); - } - width = width > 0 ? width : 100; - n = false; - rs = {}; - if (~mimetype.indexOf('google-apps') || ~mimetype.indexOf('pdf')) { - n = true; - turl = thumbUrl.replace(r[r.length - 1], "s10000"); - rs = GetResizedSize.call(this, GetImage.call(this, turl, "png"), width); - } else if (~mimetype.indexOf('image')) { - rs = GetResizedSize.call(this, DriveApp.getFileById(fileId).getBlob(), width); - } else { - turl = thumbUrl.replace(r[r.length - 1], "s10000"); - rs = GetResizedSize.call(this, GetImage.call(this, turl, "png"), width); - } - blob = GetImage.call(this, thumbUrl.replace(r[r.length - 1], "s" + (n ? rs.reheight : rs.rewidth))); - resized = this.GetSize(blob); - return { - blob: blob, - identification: resized.identification, - originalwidth: rs.orgwidth, - originalheight: rs.orgheight, - resizedwidth: resized.width, - resizedheight: resized.height - }; - } - - // GetSize -------------------------------------------------------------------------------- - GetSize(blob) { - var res; - this.bytear = (function(blob) { - var e; - try { - return blob.getBytes(); - } catch (error) { - e = error; - throw new Error("Cannot retrieve file blob."); - } - })(blob); - getFormat.call(this); - switch (this.format) { - case "bmp": - res = getInfBMP.call(this); - break; - case "gif": - res = getInfGIF.call(this); - break; - case "png": - res = getInfPNG.call(this); - break; - case "jpg": - res = getInfJPG.call(this); - break; - default: - res = { - Error: this.format - }; - } - return res; - } - - }; - - ImgApp.name = "ImgApp"; - - mergeImages = function(obj_) { - var canvas, croppedBlob, object, presentationId, rs, slide, slides; - canvas = obj_.merge.reduce((o, r) => { +(function(r) { + var ImgApp; + ImgApp = (function() { + var GetImage, GetResizedSize, byte2hex, byte2hexNum, byte2num, cropImage, fetch, getFormat, getImageFromSlide, getInfBMP, getInfGIF, getInfJPG, getInfPNG, hex2num, mergeImages, pixelToEmu, pixelToPt, ptToEmu, ptToPixel; + + ImgApp.name = "ImgApp"; + + function ImgApp(blob) { + this.bytear = []; + } + + ImgApp.prototype.EditImage = function(obj_) { + if (obj_.hasOwnProperty("blob") && obj_.hasOwnProperty("crop") && obj_.blob.toString() === "Blob" && typeof obj_.crop === "object") { + return cropImage.call(this, obj_); + } else if (obj_.hasOwnProperty("merge") && Array.isArray(obj_.merge) && Array.isArray(obj_.merge[0])) { + return mergeImages.call(this, obj_); + } else { + throw new Error("Wrong object. Please confirm it again."); + } + }; + + mergeImages = function(obj_) { + var canvas, croppedBlob, object, presentationId, rs, slide, slides; + canvas = obj_.merge.reduce((function(_this) { + return function(o, r) { var ar, mHeight, mWidth; mWidth = 0; mHeight = 0; ar = []; - r.forEach((c) => { + r.forEach(function(c) { var temp; if (c && c.toString() === "Blob") { - temp = this.GetSize(c); + temp = _this.GetSize(c); if (temp.width * temp.height > 25000000) { throw new Error("The image size is too large. Please check https://gist.github.com/tanaikech/9414d22de2ff30216269ca7be4bce462"); } @@ -242,281 +123,392 @@ function editImage(object) { } o.maxHeight += mHeight; return o; - }, { - maxWidth: 0, - maxHeight: 0, - images: [] - }); - object = { - title: "tempForImaApp", - width: { - unit: "pixel", - size: canvas.maxWidth - }, - height: { - unit: "pixel", - size: canvas.maxHeight - } }; - presentationId = (new SlidesAppp("create")).createNewSlidesWithPageSize(object); - slides = SlidesApp.openById(presentationId); - slide = slides.getSlides()[0]; - canvas.images.forEach(function(r) { - r.forEach(function(c) { - if (c) { - slide.insertImage(c.blob, pixelToPt.call(this, c.left), pixelToPt.call(this, c.top), pixelToPt.call(this, c.width), pixelToPt.call(this, c.height)); - } - }); - }); - slides.saveAndClose(); - rs = canvas.maxWidth > 1600 ? 1600 : canvas.maxWidth; - if (obj_.hasOwnProperty("outputWidth") && obj_.outputWidth > 0 && obj_.outputWidth <= 1600) { - rs = obj_.outputWidth; + })(this), { + maxWidth: 0, + maxHeight: 0, + images: [] + }); + object = { + title: "tempForImaApp", + width: { + unit: "pixel", + size: canvas.maxWidth + }, + height: { + unit: "pixel", + size: canvas.maxHeight } - croppedBlob = getImageFromSlide.call(this, presentationId, slide.getObjectId(), rs, obj_.outputFilename); - DriveApp.getFileById(presentationId).setTrashed(true); - return croppedBlob; }; - - cropImage = function(obj_) { - var _, b, croppedBlob, height, l, object, presentationId, rs, rsHeight, rsWidth, setHeight, setL, setT, setWidth, size, slide, slides, t, unit, width; - unit = obj_.hasOwnProperty("unit") && typeof obj_.unit === "string" ? obj_.unit : "pixel"; - size = this.GetSize(obj_.blob); - if (size.width * size.height > 25000000) { - throw new Error("The image size is too large. Please check https://gist.github.com/tanaikech/9414d22de2ff30216269ca7be4bce462"); - } - width = obj_.unit === "point" ? pixelToPt.call(this, size.width) : size.width; - height = obj_.unit === "point" ? pixelToPt.call(this, size.height) : size.height; - [t, b, l, r] = ["t", "b", "l", "r"].map(function(k) { - if (obj_.crop.hasOwnProperty(k)) { - return Number(obj_.crop[k]); - } else { - return 0; + presentationId = (new SlidesAppp("create")).createNewSlidesWithPageSize(object); + slides = SlidesApp.openById(presentationId); + slide = slides.getSlides()[0]; + canvas.images.forEach(function(r) { + r.forEach(function(c) { + if (c) { + slide.insertImage(c.blob, pixelToPt.call(this, c.left), pixelToPt.call(this, c.top), pixelToPt.call(this, c.width), pixelToPt.call(this, c.height)); } }); - object = { - title: "tempForImaApp", - width: { - unit: obj_.unit, - size: width - r - l - }, - height: { - unit: obj_.unit, - size: height - b - t - } - }; - presentationId = (new SlidesAppp("create")).createNewSlidesWithPageSize(object); - slides = SlidesApp.openById(presentationId); - slide = slides.getSlides()[0]; - setWidth = obj_.unit === "pixel" ? pixelToPt.call(this, width) : width; - setHeight = obj_.unit === "pixel" ? pixelToPt.call(this, height) : height; - setL = obj_.unit === "pixel" ? pixelToPt.call(this, l) : l; - setT = obj_.unit === "pixel" ? pixelToPt.call(this, t) : t; - _ = slide.insertImage(obj_.blob, -setL, -setT, setWidth, setHeight); - slides.saveAndClose(); - rsWidth = size.width - (obj_.unit === "point" ? ptToPixel.call(this, l) : l) - (obj_.unit === "point" ? ptToPixel.call(this, r) : r); - rsHeight = size.height - (obj_.unit === "point" ? ptToPixel.call(this, t) : t) - (obj_.unit === "point" ? ptToPixel.call(this, b) : b); - if (obj_.hasOwnProperty("outputWidth") && obj_.outputWidth > 0 && obj_.outputWidth <= 1600) { - rsWidth = obj_.unit === "point" ? ptToPixel.call(this, obj_.outputWidth) : obj_.outputWidth; + }); + slides.saveAndClose(); + rs = canvas.maxWidth > 1600 ? 1600 : canvas.maxWidth; + if (obj_.hasOwnProperty("outputWidth") && obj_.outputWidth > 0 && obj_.outputWidth <= 1600) { + rs = obj_.outputWidth; + } + croppedBlob = getImageFromSlide.call(this, presentationId, slide.getObjectId(), rs, obj_.outputFilename); + DriveApp.getFileById(presentationId).setTrashed(true); + return croppedBlob; + }; + + cropImage = function(obj_) { + var _, b, croppedBlob, height, l, object, presentationId, ref, rs, rsHeight, rsWidth, setHeight, setL, setT, setWidth, size, slide, slides, t, unit, width; + unit = obj_.hasOwnProperty("unit") && typeof obj_.unit === "string" ? obj_.unit : "pixel"; + size = this.GetSize(obj_.blob); + if (size.width * size.height > 25000000) { + throw new Error("The image size is too large. Please check https://gist.github.com/tanaikech/9414d22de2ff30216269ca7be4bce462"); + } + width = obj_.unit === "point" ? pixelToPt.call(this, size.width) : size.width; + height = obj_.unit === "point" ? pixelToPt.call(this, size.height) : size.height; + ref = ["t", "b", "l", "r"].map(function(k) { + if (obj_.crop.hasOwnProperty(k)) { + return Number(obj_.crop[k]); + } else { + return 0; } - if (obj_.hasOwnProperty("outputHeight") && obj_.outputHeight > 0 && obj_.outputHeight <= 1600) { - rsHeight = obj_.unit === "point" ? ptToPixel.call(this, obj_.outputHeight) : obj_.outputHeight; + }), t = ref[0], b = ref[1], l = ref[2], r = ref[3]; + object = { + title: "tempForImaApp", + width: { + unit: obj_.unit, + size: width - r - l + }, + height: { + unit: obj_.unit, + size: height - b - t } - rs = Math.max(rsWidth, rsHeight); - croppedBlob = getImageFromSlide.call(this, presentationId, slide.getObjectId(), rs, obj_.blob.getName()); - DriveApp.getFileById(presentationId).setTrashed(true); - return croppedBlob; - }; - - ptToPixel = function(pt_) { - return pt_ * 1.33333; - }; - - ptToEmu = function(pt_) { - return pt_ * 12700; }; - - pixelToPt = function(pixel_) { - return pixel_ * 0.75; - }; - - pixelToEmu = function(pixel_) { - return pixel_ * 0.75 * 12700; - }; - - getImageFromSlide = function(presentationId, slideId, rs, filename) { - var croppedBlob, e, er, resObj, url; - croppedBlob = null; + presentationId = (new SlidesAppp("create")).createNewSlidesWithPageSize(object); + slides = SlidesApp.openById(presentationId); + slide = slides.getSlides()[0]; + setWidth = obj_.unit === "pixel" ? pixelToPt.call(this, width) : width; + setHeight = obj_.unit === "pixel" ? pixelToPt.call(this, height) : height; + setL = obj_.unit === "pixel" ? pixelToPt.call(this, l) : l; + setT = obj_.unit === "pixel" ? pixelToPt.call(this, t) : t; + _ = slide.insertImage(obj_.blob, -setL, -setT, setWidth, setHeight); + slides.saveAndClose(); + rsWidth = size.width - (obj_.unit === "point" ? ptToPixel.call(this, l) : l) - (obj_.unit === "point" ? ptToPixel.call(this, r) : r); + rsHeight = size.height - (obj_.unit === "point" ? ptToPixel.call(this, t) : t) - (obj_.unit === "point" ? ptToPixel.call(this, b) : b); + if (obj_.hasOwnProperty("outputWidth") && obj_.outputWidth > 0 && obj_.outputWidth <= 1600) { + rsWidth = obj_.unit === "point" ? ptToPixel.call(this, obj_.outputWidth) : obj_.outputWidth; + } + if (obj_.hasOwnProperty("outputHeight") && obj_.outputHeight > 0 && obj_.outputHeight <= 1600) { + rsHeight = obj_.unit === "point" ? ptToPixel.call(this, obj_.outputHeight) : obj_.outputHeight; + } + rs = Math.max(rsWidth, rsHeight); + croppedBlob = getImageFromSlide.call(this, presentationId, slide.getObjectId(), rs, obj_.blob.getName()); + DriveApp.getFileById(presentationId).setTrashed(true); + return croppedBlob; + }; + + ptToPixel = function(pt_) { + return pt_ * 1.33333; + }; + + ptToEmu = function(pt_) { + return pt_ * 12700; + }; + + pixelToPt = function(pixel_) { + return pixel_ * 0.75; + }; + + pixelToEmu = function(pixel_) { + return pixel_ * 0.75 * 12700; + }; + + getImageFromSlide = function(presentationId, slideId, rs, filename) { + var croppedBlob, e, er, resObj, url; + croppedBlob = null; + try { + resObj = Slides.Presentations.Pages.getThumbnail(presentationId, slideId, { + "thumbnailProperties.thumbnailSize": "LARGE", + "thumbnailProperties.mimeType": "PNG" + }); try { - resObj = Slides.Presentations.Pages.getThumbnail(presentationId, slideId, { - "thumbnailProperties.thumbnailSize": "LARGE", - "thumbnailProperties.mimeType": "PNG" - }); - try { - url = resObj.contentUrl.replace(/=s\d+/, "=s" + Math.ceil(rs)); - croppedBlob = UrlFetchApp.fetch(url).getBlob(); - } catch (error) { - er = error; - throw new Error(er.message); - } - croppedBlob = croppedBlob.setName(filename || "outputImageFromImgApp.png"); + url = resObj.contentUrl.replace(/=s\d+/, "=s" + Math.ceil(rs)); + croppedBlob = UrlFetchApp.fetch(url).getBlob(); } catch (error) { - e = error; - if (e.message === "Slides is not defined") { - throw new Error("Please enable Slides API at Advanced Google services, and try again."); - } else { - throw new Error(e.message); - } + er = error; + throw new Error(er.message); } - return croppedBlob; - }; - - GetImage = function(turl) { - return UrlFetchApp.fetch(turl, { - headers: { - Authorization: "Bearer " + ScriptApp.getOAuthToken() - } - }).getBlob(); - }; - - GetResizedSize = function(blob, width) { - var oh, ow, rh, rw, size; - size = this.GetSize(blob); - ow = size.width; - oh = size.height; - if (width > ow) { - rw = ow; - rh = oh; + croppedBlob = croppedBlob.setName(filename || "outputImageFromImgApp.png"); + } catch (error) { + e = error; + if (e.message === "Slides is not defined") { + throw new Error("Please enable Slides API at Advanced Google services, and try again."); } else { - rw = width; - rh = Math.ceil(width * oh / ow); + throw new Error(e.message); } - return { - orgwidth: ow, - orgheight: oh, - rewidth: rw, - reheight: rh - }; - }; - - getInfBMP = function() { - return { - identification: "BMP", - width: byte2num(this.bytear.slice(18, 22), true), - height: byte2num(this.bytear.slice(22, 26), true), - filesize: this.bytear.length - }; - }; - - getInfGIF = function() { - return { - identification: "GIF", - width: byte2num(this.bytear.slice(6, 8), true), - height: byte2num(this.bytear.slice(8, 10), true), - filesize: this.bytear.length - }; - }; - - getInfPNG = function() { - return { - identification: "PNG", - width: byte2num(this.bytear.slice(16, 20), false), - height: byte2num(this.bytear.slice(20, 24), false), - filesize: this.bytear.length - }; - }; - - getInfJPG = function() { - var i, ma; - i = 0; - while (i < this.bytear.length) { - i += 1; - if ((byte2hexNum.call(this, this.bytear[i])) === "ff") { - i += 1; - ma = byte2hexNum.call(this, this.bytear[i]); - if (ma === "c0" || ma === "c1" || ma === "c2") { - break; - } else { - i += hex2num.call(this, byte2hex.call(this, this.bytear.slice(i + 1, i + 3))); - } + } + return croppedBlob; + }; + + ImgApp.prototype.UpdateThumbnail = function(imgFileId_, srcFileId_) { + var boundary, data, fields, headers, img4thumb, metadata, method, mime, payload, url; + if (imgFileId_ == null) { + throw new Error("No image file ID."); + } + if (srcFileId_ == null) { + throw new Error("No source file ID."); + } + img4thumb = DriveApp.getFileById(imgFileId_); + mime = img4thumb.getMimeType(); + if (mime !== "image/png" && mime !== "image/gif" && mime !== "image/hpeg") { + throw new Error("The image format (" + mime + ") cannot be used for thumbnail."); + } + metadata = { + contentHints: { + thumbnail: { + image: Utilities.base64EncodeWebSafe(img4thumb.getBlob().getBytes()), + mimeType: mime } } - return { - identification: "JPG", - width: hex2num.call(this, byte2hex.call(this, this.bytear.slice(i + 6, i + 8))), - height: hex2num.call(this, byte2hex.call(this, this.bytear.slice(i + 4, i + 6))), - filesize: this.bytear.length - }; }; - - getFormat = function() { - var f; - f = (byte2hex.call(this, this.bytear.slice(0, 8))).join(""); - this.format = f.slice(0, 16) === "89504e470d0a1a0a" ? "png" : f.slice(0, 4) === "ffd8" ? "jpg" : f.slice(0, 6) === "474946" ? "gif" : f.slice(0, 4) === "424d" ? "bmp" : "Cannot retrieve image size. Now, it can retrive image size from png, jpg, gif and bmp."; + fields = "id,mimeType,name,thumbnailVersion,thumbnailLink"; + url = "https://www.googleapis.com/upload/drive/v3/files/" + srcFileId_ + "?uploadType=multipart&fields=" + encodeURIComponent(fields); + boundary = "xxxxxxxxxx"; + data = "--" + boundary + "\r\n"; + data += "Content-Disposition: form-data; name=\"metadata\"\r\n"; + data += "Content-Type: application/json; charset=UTF-8\r\n\r\n"; + data += JSON.stringify(metadata) + "\r\n"; + data += "--" + boundary + "--\r\n"; + payload = Utilities.newBlob(data).getBytes(); + headers = { + "Authorization": "Bearer " + ScriptApp.getOAuthToken(), + "Content-Type": "multipart/related; boundary=" + boundary }; - - byte2hexNum = function(data) { - var conv; - conv = (data < 0 ? data + 256 : data).toString(16); - return (conv.length === 1 ? "0" + conv : conv); - }; - - byte2hex = function(data) { - return data.map(function(e) { - return (e < 0 ? e + 256 : e).toString(16); - }).map(function(e) { - return (e.length === 1 ? "0" + e : e); - }); + method = "patch"; + return fetch.call(this, url, method, payload, headers); + }; + + ImgApp.prototype.DoResize = function(fileId, width) { + var blob, e, headers, method, mimetype, n, res, resized, rs, thumbUrl, turl, url; + try { + url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?fields=thumbnailLink%2CmimeType"; + method = "get"; + headers = { + "Authorization": "Bearer " + ScriptApp.getOAuthToken() + }; + res = fetch.call(this, url, method, null, headers); + thumbUrl = res.thumbnailLink; + mimetype = res.mimeType; + r = thumbUrl.split("="); + } catch (error) { + e = error; + throw new Error("'" + fileId + "' is not compatible file. Error message is " + JSON.stringify(e)); + } + width = width > 0 ? width : 100; + n = false; + rs = {}; + if (~mimetype.indexOf('google-apps') || ~mimetype.indexOf('pdf')) { + n = true; + turl = thumbUrl.replace(r[r.length - 1], "s10000"); + rs = GetResizedSize.call(this, GetImage.call(this, turl, "png"), width); + } else if (~mimetype.indexOf('image')) { + rs = GetResizedSize.call(this, DriveApp.getFileById(fileId).getBlob(), width); + } else { + turl = thumbUrl.replace(r[r.length - 1], "s10000"); + rs = GetResizedSize.call(this, GetImage.call(this, turl, "png"), width); + } + blob = GetImage.call(this, thumbUrl.replace(r[r.length - 1], "s" + (n ? rs.reheight : rs.rewidth))); + resized = this.GetSize(blob); + return { + blob: blob, + identification: resized.identification, + originalwidth: rs.orgwidth, + originalheight: rs.orgheight, + resizedwidth: resized.width, + resizedheight: resized.height }; + }; - byte2num = function(data, byteorder) { - var conv; - if (byteorder) { - conv = data.reduceRight(function(ar, e) { - var temp; - temp = (e < 0 ? e + 256 : e).toString(16); - if (temp.length === 1) { - temp = "0" + temp; - } - ar.push(temp); - return ar; - }, []); - } else { - conv = byte2hex.call(this, data); + GetImage = function(turl) { + return UrlFetchApp.fetch(turl, { + headers: { + Authorization: "Bearer " + ScriptApp.getOAuthToken() } - return hex2num.call(this, conv); - }; - - hex2num = function(data) { - return parseInt(data.join(""), 16); + }).getBlob(); + }; + + GetResizedSize = function(blob, width) { + var oh, ow, rh, rw, size; + size = this.GetSize(blob); + ow = size.width; + oh = size.height; + if (width > ow) { + rw = ow; + rh = oh; + } else { + rw = width; + rh = Math.ceil(width * oh / ow); + } + return { + orgwidth: ow, + orgheight: oh, + rewidth: rw, + reheight: rh }; + }; - fetch = function(url, method, payload, headers) { - var e, res; + ImgApp.prototype.GetSize = function(blob) { + var res; + this.bytear = (function(blob) { + var e; try { - res = UrlFetchApp.fetch(url, { - method: method, - payload: payload, - headers: headers, - muteHttpExceptions: true - }); + return blob.getBytes(); } catch (error) { e = error; - throw new Error(e); + throw new Error("Cannot retrieve file blob."); } - try { - r = JSON.parse(res.getContentText()); - } catch (error) { - e = error; - r = res.getContentText(); + })(blob); + getFormat.call(this); + switch (this.format) { + case "bmp": + res = getInfBMP.call(this); + break; + case "gif": + res = getInfGIF.call(this); + break; + case "png": + res = getInfPNG.call(this); + break; + case "jpg": + res = getInfJPG.call(this); + break; + default: + res = { + Error: this.format + }; + } + return res; + }; + + getInfBMP = function() { + return { + identification: "BMP", + width: byte2num(this.bytear.slice(18, 22), true), + height: byte2num(this.bytear.slice(22, 26), true), + filesize: this.bytear.length + }; + }; + + getInfGIF = function() { + return { + identification: "GIF", + width: byte2num(this.bytear.slice(6, 8), true), + height: byte2num(this.bytear.slice(8, 10), true), + filesize: this.bytear.length + }; + }; + + getInfPNG = function() { + return { + identification: "PNG", + width: byte2num(this.bytear.slice(16, 20), false), + height: byte2num(this.bytear.slice(20, 24), false), + filesize: this.bytear.length + }; + }; + + getInfJPG = function() { + var i, ma; + i = 0; + while (i < this.bytear.length) { + i += 1; + if ((byte2hexNum.call(this, this.bytear[i])) === "ff") { + i += 1; + ma = byte2hexNum.call(this, this.bytear[i]); + if (ma === "c0" || ma === "c1" || ma === "c2") { + break; + } else { + i += hex2num.call(this, byte2hex.call(this, this.bytear.slice(i + 1, i + 3))); + } } - return r; + } + return { + identification: "JPG", + width: hex2num.call(this, byte2hex.call(this, this.bytear.slice(i + 6, i + 8))), + height: hex2num.call(this, byte2hex.call(this, this.bytear.slice(i + 4, i + 6))), + filesize: this.bytear.length }; - - return ImgApp; - - }).call(this); - return r.ImgApp = ImgApp; - })(this); - -}).call(this); + }; + + getFormat = function() { + var f; + f = (byte2hex.call(this, this.bytear.slice(0, 8))).join(""); + this.format = f.slice(0, 16) === "89504e470d0a1a0a" ? "png" : f.slice(0, 4) === "ffd8" ? "jpg" : f.slice(0, 6) === "474946" ? "gif" : f.slice(0, 4) === "424d" ? "bmp" : "Cannot retrieve image size. Now, it can retrive image size from png, jpg, gif and bmp."; + }; + + byte2hexNum = function(data) { + var conv; + conv = (data < 0 ? data + 256 : data).toString(16); + return (conv.length === 1 ? "0" + conv : conv); + }; + + byte2hex = function(data) { + return data.map(function(e) { + return (e < 0 ? e + 256 : e).toString(16); + }).map(function(e) { + return (e.length === 1 ? "0" + e : e); + }); + }; + + byte2num = function(data, byteorder) { + var conv; + if (byteorder) { + conv = data.reduceRight(function(ar, e) { + var temp; + temp = (e < 0 ? e + 256 : e).toString(16); + if (temp.length === 1) { + temp = "0" + temp; + } + ar.push(temp); + return ar; + }, []); + } else { + conv = byte2hex.call(this, data); + } + return hex2num.call(this, conv); + }; + + hex2num = function(data) { + return parseInt(data.join(""), 16); + }; + + fetch = function(url, method, payload, headers) { + var e, res; + try { + res = UrlFetchApp.fetch(url, { + method: method, + payload: payload, + headers: headers, + muteHttpExceptions: true + }); + } catch (error) { + e = error; + throw new Error(e); + } + try { + r = JSON.parse(res.getContentText()); + } catch (error) { + e = error; + r = res.getContentText(); + } + return r; + }; + + return ImgApp; + + })(); + return r.ImgApp = ImgApp; +})(this); diff --git a/README.md b/README.md index 7fdd0f5..c38cfce 100644 --- a/README.md +++ b/README.md @@ -411,4 +411,8 @@ This is a sample script for reducing the image data size using Google Apps Scrip Added new method. Added [editImage()](#editimage) +- v1.3.1 (December 20, 2022) + + Updated by [this pull request](https://github.com/tanaikech/ImgApp/pull/11). + [TOP](#top)