diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d86a0c4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/resize-base64.code-workspace diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c4526cb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.2.1] - 2020-03-06 +### Fixed +- fixed link in CHANGELOG file + +## [1.2.0] - 2020-03-06 +### Added +- added CHANGELOG file +- added LICENSE file + +## [1.1.3] - 2018-11-26 +### Removed +- removed conditions in function resizeBase64ForMaxWidthAndMaxHeight to allow free resizing + +[Unreleased]: https://github.com/hendrik-scholz/resize-base64/compare/1.2.1...HEAD +[1.2.1]: https://github.com/hendrik-scholz/resize-base64/compare/1.2.0...1.2.1 +[1.2.0]: https://github.com/hendrik-scholz/resize-base64/compare/1.1.3...1.2.0 +[1.1.3]: https://github.com/hendrik-scholz/resize-base64/releases/tag/1.1.3 \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..df41899 --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +ISC License (ISC) + +Copyright 2020 hendrik-scholz + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index a839b85..8e3a65b 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,73 @@ -## When passing an image base64 as first argument to the function, it returns the base64 of the resized image. maxWidth and maxHeight are optional. +# resize-base64 -#### Note: This is a font-end package. +Functions that resize a Base64 image. Pass a Base64 string of an image, the maximum width, the maximum height, a success callback, and an error callback to the function. The function returns the resized image in the success callback. +| Function | Description | +| ------ | ----------- | +| resizeBase64ForMaxWidth | resizes an image to the maximum width, the aspect ratio of the image is maintained | +| resizeBase64ForMaxHeight | resizes an image to the maximum height, the aspect ratio of the image is maintained | +| resizeBase64ForMaxWidthAndMaxHeight | resizes an image to the maximum width and maximum height, the aspect ratio of the image is not maintained | -#### What is it for? -`If you have a base64 image and you would like to resize it, this function will return a base64 image resizes to your height and width specifications.` +Every function takes the parameters listed below. +| Parameter | Description | +| ------ | ----------- | +| base64String | the image to resize as a Base64 string | +| maxWidth | the maxmium width that the image should be resized to | +| maxHeight | the maxmium height that the image should be resized to | +| successCallback | the callback that contains the resized image as a Base64 string | +| errorCallback | the callback that contains the error that occurred during resizing | -#### How do I install it? -`bower install resize-base64 --save` +## Restrictions +* The function can only be used in frontend code. +* Since enlarging images is not desirable due to the loss of quality, the functions resizeBase64ForMaxWidth and resizeBase64ForMaxHeight do not support it. Use the function resizeBase64ForMaxWidthAndMaxHeight for free resizing (shrinking and enlarging). +## Installation -##### To use ``` -var image = resizebase64(base64, maxWidth, maxHeight); +npm i --save https://github.com/hendrik-scholz/resize-base64/#master +``` + +## Test + +1. Copy the index.js and the test folder with all its files to an HTTP server. +2. Request the HTML file for the test case in the browser, e.g. http://localhost/resize-base64/test/resizeBase64ImageFrom320x240ToMaxHeight120.html + +## Example + +``` + + + + + + + + + + + ``` +See test/resizeBase64ImageFrom320x240ToMaxHeight120.html for details. +![Resize Example](screenshots/resize.png "Resize Example") \ No newline at end of file diff --git a/bower.json b/bower.json deleted file mode 100644 index 44c9ce2..0000000 --- a/bower.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "resize-base64", - "description": "A function that resizes a base64 image", - "main": "index.js", - "authors": [ - "Daniel Izhar (http://daniwebmaster.com)" - ], - "license": "ISC", - "keywords": [ - "resize", - "base64", - "image", - "picture" - ], - "homepage": "https://github.com/dizhar/resize-base64", - "private": true, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ] -} diff --git a/index.js b/index.js index ceeb5e2..2d1a3bb 100644 --- a/index.js +++ b/index.js @@ -1,36 +1,143 @@ - resizebase64 = function(base64, maxWidth, maxHeight){ - - -// Max size for thumbnail - if(typeof(maxWidth) === 'undefined') maxWidth = 500; - if(typeof(maxHeight) === 'undefined') maxHeight = 500; - - // Create and initialize two canvas - var canvas = document.createElement("canvas"); - var ctx = canvas.getContext("2d"); - var canvasCopy = document.createElement("canvas"); - var copyContext = canvasCopy.getContext("2d"); - - // Create original image - var img = new Image(); - img.src = base64; - - // Determine new ratio based on max size - var ratio = 1; - if(img.width > maxWidth) - ratio = maxWidth / img.width; - else if(img.height > maxHeight) - ratio = maxHeight / img.height; - - // Draw original image in second canvas - canvasCopy.width = img.width; - canvasCopy.height = img.height; - copyContext.drawImage(img, 0, 0); - - // Copy and resize second canvas to first canvas - canvas.width = img.width * ratio; - canvas.height = img.height * ratio; - ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height); - - return canvas.toDataURL(); -} \ No newline at end of file +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + }; +} + +const DEFAULT_RATIO = 1; + +function validateInput(base64String, maxWidth, maxHeight) { + let validationResult = { + isValid: false, + errorMessage: 'An error occurred.' + }; + + if(!base64String) { + validationResult.errorMessage = 'The input parameter base64String is ' + base64String + '.'; + } else if(typeof(base64String) != 'string') { + validationResult.errorMessage = 'The input parameter base64String is not of type \'string\'.'; + } else if(!base64String.startsWith('data:image')) { + validationResult.errorMessage = 'The input parameter base64String does not start with \'data:image\'.'; + } else if(!maxWidth) { + validationResult.errorMessage = 'The input parameter maxWidth is ' + maxWidth + '.'; + } else if(typeof(maxWidth) != 'number') { + validationResult.errorMessage = 'The input parameter maxWidth is not of type \'number\'.'; + } else if(maxWidth < 2) { + validationResult.errorMessage = 'The input parameter maxWidth must be at least 2 pixel.'; + } else if(!maxHeight) { + validationResult.errorMessage = 'The input parameter maxHeight is ' + maxHeight + '.'; + } else if(typeof(maxHeight) != 'number') { + validationResult.errorMessage = 'The input parameter maxHeight is not of type \'number\'.'; + } else if(maxHeight < 2) { + validationResult.errorMessage = 'The input parameter maxHeight must be at least 2 pixel.'; + } else { + validationResult.isValid = true; + validationResult.errorMessage = null; + } + + return validationResult; +} + +function maxWidthRatioFunction(imageWidth, imageHeight, targetWidth, targetHeight) { + let ratio = DEFAULT_RATIO; + + if(imageWidth > targetWidth) { + ratio = targetWidth / imageWidth; + } + + return { + width: ratio, + height: ratio + }; +} + +function maxHeightRatioFunction(imageWidth, imageHeight, targetWidth, targetHeight) { + let ratio = DEFAULT_RATIO; + + if(imageHeight > targetHeight) { + ratio = targetHeight / imageHeight; + } + + return { + width: ratio, + height: ratio + }; +} + +function maxWidthMaxHeightRatioFunction(imageWidth, imageHeight, targetWidth, targetHeight) { + let widthRatio = targetWidth / imageWidth; + let heightRatio = targetHeight / imageHeight; + + return { + width: widthRatio, + height: heightRatio + }; +} + +function resizeBase64ForMaxWidth(base64String, maxWidth, maxHeight, successCallback, errorCallback) { + let validationResult = validateInput(base64String, maxWidth, maxHeight); + + if(validationResult.isValid === true) { + resizeBase64(base64String, maxWidth, maxHeight, maxWidthRatioFunction, successCallback, errorCallback); + } else { + errorCallback(validationResult.errorMessage); + } +} + +function resizeBase64ForMaxHeight(base64String, maxWidth, maxHeight, successCallback, errorCallback) { + let validationResult = validateInput(base64String, maxWidth, maxHeight); + + if(validationResult.isValid === true) { + resizeBase64(base64String, maxWidth, maxHeight, maxHeightRatioFunction, successCallback, errorCallback); + } else { + errorCallback(validationResult.errorMessage); + } +} + +function resizeBase64ForMaxWidthAndMaxHeight(base64String, maxWidth, maxHeight, successCallback, errorCallback) { + let validationResult = validateInput(base64String, maxWidth, maxHeight); + + if(validationResult.isValid === true) { + resizeBase64(base64String, maxWidth, maxHeight, maxWidthMaxHeightRatioFunction, successCallback, errorCallback); + } else { + errorCallback(validationResult.errorMessage); + } +} + +function resizeBase64(base64String, maxWidth, maxHeight, ratioFunction, successCallback, errorCallback) { + // Create and initialize two canvas + let canvas = document.createElement("canvas"); + let ctx = canvas.getContext("2d"); + let canvasCopy = document.createElement("canvas"); + let copyContext = canvasCopy.getContext("2d"); + + // Create original image + let img = new Image(); + img.src = base64String; + + img.onload = function() { + let ratioResult = ratioFunction(img.width, img.height, maxWidth, maxHeight); + let widthRatio = ratioResult.width; + let heightRatio = ratioResult.height; + + // Draw original image in second canvas + canvasCopy.width = img.width; + canvasCopy.height = img.height; + copyContext.drawImage(img, 0, 0); + + // Copy and resize second canvas to first canvas + canvas.width = img.width * widthRatio; + canvas.height = img.height * heightRatio; + ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height); + + successCallback(canvas.toDataURL()); + }; + + img.onerror = function() { + errorCallback('Error while loading image.'); + }; +}; + +export { resizeBase64ForMaxWidth }; +export { resizeBase64ForMaxHeight }; +export { resizeBase64ForMaxWidthAndMaxHeight }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e589811 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "resize-base64", + "version": "1.2.1", + "lockfileVersion": 1 +} diff --git a/package.json b/package.json index d5443bb..4ec98a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,11 @@ { "name": "resize-base64", - "version": "1.0.13", - "description": "A function that resizes a base64 image", + "version": "1.2.1", + "description": "A function that resizes a Base64 image", + "files": [ + "index.js", + "README.md" + ], "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -13,8 +17,13 @@ "picture" ], "author": "Daniel Izhar (http://daniwebmaster.com)", - "license": "ISC", - "dependencies": { - "create-readme": "^1.1.0" - } + "contributors": [ + { + "name": "Hendrik Scholz" + } + ], + "bugs": { + "url": "https://github.com/hendrik-scholz/resize-base64/issues" + }, + "license": "ISC" } diff --git a/screenshots/resize.png b/screenshots/resize.png new file mode 100644 index 0000000..3599ca8 Binary files /dev/null and b/screenshots/resize.png differ diff --git a/test/resizeBase64ImageFrom320x240ToMaxHeight120.html b/test/resizeBase64ImageFrom320x240ToMaxHeight120.html new file mode 100644 index 0000000..909c6b1 --- /dev/null +++ b/test/resizeBase64ImageFrom320x240ToMaxHeight120.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageFrom320x240ToMaxHeight480.html b/test/resizeBase64ImageFrom320x240ToMaxHeight480.html new file mode 100644 index 0000000..009c9b9 --- /dev/null +++ b/test/resizeBase64ImageFrom320x240ToMaxHeight480.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageFrom320x240ToMaxWidth100xMaxHeight100.html b/test/resizeBase64ImageFrom320x240ToMaxWidth100xMaxHeight100.html new file mode 100644 index 0000000..28db79e --- /dev/null +++ b/test/resizeBase64ImageFrom320x240ToMaxWidth100xMaxHeight100.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageFrom320x240ToMaxWidth160.html b/test/resizeBase64ImageFrom320x240ToMaxWidth160.html new file mode 100644 index 0000000..87222de --- /dev/null +++ b/test/resizeBase64ImageFrom320x240ToMaxWidth160.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageFrom320x240ToMaxWidth640.html b/test/resizeBase64ImageFrom320x240ToMaxWidth640.html new file mode 100644 index 0000000..581ad8c --- /dev/null +++ b/test/resizeBase64ImageFrom320x240ToMaxWidth640.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageInvalidBase64String.html b/test/resizeBase64ImageInvalidBase64String.html new file mode 100644 index 0000000..448b602 --- /dev/null +++ b/test/resizeBase64ImageInvalidBase64String.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageInvalidPrefix.html b/test/resizeBase64ImageInvalidPrefix.html new file mode 100644 index 0000000..b67ff2a --- /dev/null +++ b/test/resizeBase64ImageInvalidPrefix.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxHeight0Pixel.html b/test/resizeBase64ImageMaxHeight0Pixel.html new file mode 100644 index 0000000..c82d5cd --- /dev/null +++ b/test/resizeBase64ImageMaxHeight0Pixel.html @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxHeight1Pixel.html b/test/resizeBase64ImageMaxHeight1Pixel.html new file mode 100644 index 0000000..3266f24 --- /dev/null +++ b/test/resizeBase64ImageMaxHeight1Pixel.html @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxHeightNotOfTypeNumber.html b/test/resizeBase64ImageMaxHeightNotOfTypeNumber.html new file mode 100644 index 0000000..092d86b --- /dev/null +++ b/test/resizeBase64ImageMaxHeightNotOfTypeNumber.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxHeightNull.html b/test/resizeBase64ImageMaxHeightNull.html new file mode 100644 index 0000000..d25d9a3 --- /dev/null +++ b/test/resizeBase64ImageMaxHeightNull.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxHeightUndefined.html b/test/resizeBase64ImageMaxHeightUndefined.html new file mode 100644 index 0000000..d6b48f1 --- /dev/null +++ b/test/resizeBase64ImageMaxHeightUndefined.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxWidth0Pixel.html b/test/resizeBase64ImageMaxWidth0Pixel.html new file mode 100644 index 0000000..02ca69f --- /dev/null +++ b/test/resizeBase64ImageMaxWidth0Pixel.html @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxWidth1Pixel.html b/test/resizeBase64ImageMaxWidth1Pixel.html new file mode 100644 index 0000000..15d5c3d --- /dev/null +++ b/test/resizeBase64ImageMaxWidth1Pixel.html @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxWidthNotOfTypeNumber.html b/test/resizeBase64ImageMaxWidthNotOfTypeNumber.html new file mode 100644 index 0000000..b40b384 --- /dev/null +++ b/test/resizeBase64ImageMaxWidthNotOfTypeNumber.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxWidthNull.html b/test/resizeBase64ImageMaxWidthNull.html new file mode 100644 index 0000000..c407859 --- /dev/null +++ b/test/resizeBase64ImageMaxWidthNull.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageMaxWidthUndefined.html b/test/resizeBase64ImageMaxWidthUndefined.html new file mode 100644 index 0000000..e9347ad --- /dev/null +++ b/test/resizeBase64ImageMaxWidthUndefined.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageNotOfTypeString.html b/test/resizeBase64ImageNotOfTypeString.html new file mode 100644 index 0000000..099a3c5 --- /dev/null +++ b/test/resizeBase64ImageNotOfTypeString.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageNull.html b/test/resizeBase64ImageNull.html new file mode 100644 index 0000000..a059e65 --- /dev/null +++ b/test/resizeBase64ImageNull.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/resizeBase64ImageUndefined.html b/test/resizeBase64ImageUndefined.html new file mode 100644 index 0000000..b9502e6 --- /dev/null +++ b/test/resizeBase64ImageUndefined.html @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file