Imageinspector
- Responder
- View
- Inspector
- ImageInspector
- Inspector
- View
Click in the image. Select a JPG, PNG, GIF or SVG file. NOTE: The maximum size of the file is configured to 1 MB and the maximum width of the display to 320 px. Move the pointer of the mouse over the image to display its dimensions. Open a folder containing images with the explorer of your file system. Drag and drop a JPG, PNG, GIF or SVG file over the image.
Try saving on your disk and loading the logo of Chrome, of Firefox or the acronym in SVG. NOTE: An SVG doesn't have a maximum size and its dimensions depend on the maximum width of the display (320 px).
To start loading an image from a file with a button, a code can run the method loadImage
of the inspector when the button is clicked.
IMPORTANT: For security reasons, loadImage
must be called in response to a user interaction.
And in JavaScript:
- function ImageInspector(value = null, options = false) {
- options = options || {};
- let filetypes = options.filetypes;
- let maxsize = options.maxsize;
- let draganddrop = options.draganddrop === undefined ? true : (options.draganddrop ? true : false);
- let loadonclick = options.loadonclick === undefined ? true : (options.loadonclick ? true : false);
- if (!this.validate(value))
- throw new TypeError();
- if (filetypes === undefined)
- filetypes = ImageInspector.defaultFileTypes;
- else if (! (Array.isArray(filetypes) && filetypes.length > 0 && filetypes.every((e) => typeof e === 'string')))
- throw new TypeError();
- if (maxsize === undefined)
- maxsize = 0;
- else if (typeof maxsize !== 'number')
- throw new TypeError();
- else if (maxsize < 0)
- throw new RangeError();
- Inspector.call(this);
- if (value !== null) {
- const [data, width, height] = value;
- this._value = data;
- this._width = width;
- this._height = height;
- }
- this._type = undefined;
- this._size = 0;
- this._filetypes = filetypes;
- this._maxsize = maxsize;
- this._draganddrop = draganddrop;
- this._loadonclick = loadonclick;
- this._imageWidget = null;
- this._imageWidgetSrc = null;
- }
- ImageInspector.prototype = Object.create(Inspector.prototype);
- Object.defineProperty(ImageInspector.prototype, 'constructor', { value: ImageInspector, enumerable: false, writable: true });
- ImageInspector.defaultFileTypes = ['image/jpeg', 'image/png', 'image/gif'];
- Object.defineProperty(ImageInspector.prototype, 'width', {
- get: function() {
- return this._width;
- }
- });
- Object.defineProperty(ImageInspector.prototype, 'height', {
- get: function() {
- return this._height;
- }
- });
- Object.defineProperty(ImageInspector.prototype, 'type', {
- get: function() {
- if (!this._value)
- return undefined;
- if (this._type === undefined)
- this._type = /^data:(image\/[-.+0-9a-zA-Z]+);base64,/.exec(this._value)[1];
- return this._type;
- }
- });
- Object.defineProperty(ImageInspector.prototype, 'size', {
- get: function() {
- if (!this._value)
- return 0;
- if (!this._size)
- this._size = atob(this._value.substring(this._value.indexOf(',')+1)).length;
- return this._size;
- }
- });
- ImageInspector.prototype.validate = function(val) {
- return val === null || (Array.isArray(val) && Validator.validateImageDataURL(val[0]) && Number.isInteger(val[1]) && Number.isInteger(val[2]) && val[1] >= 0 && val[2] >= 0);
- };
- ImageInspector.prototype.get = function() {
- return this._value ? [this._value, this._width, this._height] : null;
- };
- ImageInspector.prototype.set = function(val) {
- if (!this.validate(val))
- return false;
- const [data, width, height] = val === null ? [null, 0, 0] : val;
- if (this._value !== data) {
- this._value = data;
- this._width = width;
- this._height = height;
- this._type = undefined;
- this._size = 0;
- if (this.interfaced())
- this.resetWidget();
- }
- return true;
- };
- ImageInspector.prototype.loadImage = function() {
- if (this._widget)
- this._widget.click();
- return this;
- };
- ImageInspector.prototype.reset = function() {
- if (!this._widget)
- return false;
- if (!this._imageWidget.src)
- return false;
- this._loadurl(this._imageWidget.src);
- return true;
- };
- ImageInspector.prototype.disable = function() {
- Inspector.prototype.disable.call(this);
- if (this._imageWidget && this._loadonclick)
- this._imageWidget.style.cursor = 'default';
- return this;
- };
- ImageInspector.prototype.enable = function() {
- Inspector.prototype.enable.call(this);
- if (this._imageWidget && this._loadonclick)
- this._imageWidget.style.cursor = 'pointer';
- return this;
- };
- ImageInspector.prototype.changeCallback = function(e) {
- let val = e.target.value ? e.target.files[0] : false;
- if (val)
- this._loadblob(e.target.files[0]);
- };
- ImageInspector.prototype.resetWidget = function() {
- if (this._imageWidget) {
- this._imageWidget.src = this._value || this._imageWidgetSrc;
- this._imageWidget.setAttribute('title', this._value ? `${this._width}x${this._height}` : '');
- }
- return this;
- };
- ImageInspector.prototype.setWidget = function(w) {
- if (w.tagName != 'IMG')
- throw new TypeError();
- let input = document.createElement('input');
- input.type = 'file';
- input.accept = this._filetypes.join(',');
- input.style.display = 'none';
- Inspector.prototype.setWidget.call(this, input);
- if (this._loadonclick) {
- w.addEventListener('click', () => this.loadImage());
- w.style.cursor = this.isEnabled() ? 'pointer' : 'default';
- }
- if (this._draganddrop) {
- w.addEventListener('drop', (e) => {
- const dt = e.dataTransfer;
- e.preventDefault();
- if (dt.types.indexOf('Files') != -1) {
- this._loadblob(dt.files[0]);
- }
- });
- w.addEventListener('dragenter', (e) => {
- const dt = e.dataTransfer;
- if (dt.types.indexOf('Files') != -1) {
- e.preventDefault();
- }
- });
- w.addEventListener('dragleave', (e) => {
- e.preventDefault();
- });
- w.addEventListener('dragover', (e) => {
- const dt = e.dataTransfer;
- e.preventDefault();
- dt.dropEffect = dt.types.indexOf('Files') != -1 ? 'copy' : 'none';
- });
- }
- w.removeAttribute('width');
- w.removeAttribute('height');
- w.after(input);
- this._imageWidget = w;
- this._imageWidgetSrc = w.src;
- return this;
- };
- ImageInspector.prototype.manageWidget = function(parent = null) {
- Inspector.prototype.manageWidget.call(this, parent);
- if (this._parent && this._imageWidget)
- this._parent.appendChild(this._imageWidget);
- return this;
- };
- ImageInspector.prototype.unmanageWidget = function() {
- Inspector.prototype.unmanageWidget.call(this);
- if (this._parent && this._imageWidget)
- this._parent.removeChild(this._imageWidget);
- return this;
- };
- ImageInspector.prototype.createWidget = function() {
- const html = `<img src="${this._imageWidgetSrc}" alt="" title="" />`;
- let template = document.createElement('template');
- template.innerHTML = html;
- let widget = template.content.children[0];
- this.setWidget(widget);
- return this;
- };
- ImageInspector.prototype.destroyWidget = function() {
- Inspector.prototype.destroyWidget.call(this);
- this._imageWwidget = null;
- return this;
- };
- ImageInspector.prototype._loadurl = function(url) {
- const req = new XMLHttpRequest();
- req.open('GET', url);
- req.responseType = 'blob';
- req.setRequestHeader = this._filetypes.join(',');
- req.onload = () => this._loadblob(req.response);
- req.send();
- };
- ImageInspector.prototype._loadblob = function(blob) {
- if (this._maxsize > 0 && blob.size > this._maxsize)
- return;
- if (this._filetypes.indexOf(blob.type) == -1)
- return;
- const reader = new FileReader();
- reader.onload = (e) => {
- let data = e.target.result;
- if (this._value !== data) {
- this._value = data;
- this._width = this._height = 0;
- this._type = undefined;
- this._size = blob.size;
- if (this._imageWidget) {
- this._imageWidget.addEventListener('load', (e) => this._onloadsrc(e), { once: true });
- this._imageWidget.src = data;
- }
- }
- };
- reader.readAsDataURL(blob);
- };
- ImageInspector.prototype._onloadsrc = function(e) {
- const data = e.target.src;
- const r = /^data:(image\/[-.+0-9a-zA-Z]+);base64,/.exec(data);
- if (r) {
- const type = r[1];
- const svg = type == 'image/svg+xml';
- const w = svg ? e.target.width : e.target.naturalWidth;
- const h = svg ? e.target.height : e.target.naturalHeight;
- this._width = w;
- this._height = h;
- this._type = type;
- this._imageWidget.setAttribute('title', `${w}x${h}`);
- this.respondTo('inspectorValueChanged', this);
- }
- else
- this._imageWidget.setAttribute('title', '');
- };
Test
- <?php $filetypes=array('image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'); ?>
- <?php $maxsize=1000000; ?>
- <?php $width=320; ?>
- <?php $id=uniqid('id'); ?>
- .test_display img {
- max-width: <?php echo $width; ?>px;
- }
- <div id="<?php echo $id; ?>" class="noprint">
- <div class="test_display"><img src="/files/images/htmlcssjs.jpg" alt=""/></div>
- </div>
- <?php head('javascript', '/objectivejs/Objective.js'); ?>
- <?php head('javascript', '/objectivejs/Responder.js'); ?>
- <?php head('javascript', '/objectivejs/View.js'); ?>
- <?php head('javascript', '/objectivejs/Inspector.js'); ?>
- <?php head('javascript', '/objectivejs/ImageInspector.js'); ?>
- <?php head('javascript', '/objectivejs/Validator.js'); ?>
- const filetypes = [<?php echo implode(',', array_map(function($s) { return "'$s'"; }, $filetypes)); ?>];
- const inspector = new ImageInspector(null, { filetypes: filetypes, maxsize: <?php echo $maxsize; ?> });
- const container = document.querySelector('#<?php echo $id; ?>');
- inspector.setManagedWidget(container.querySelector('img'));
- inspector.reset();
SEE ALSO
Inspector, BooleanInspector, NumberInspector, StringInspector, SelectInspector, OptionInspector, SelectionInspector, ColorInspector, Validator
Comments