image shown rotated on iPad and not on laptop - javascript

I've created a small test site in which you can upload a picture. And without a round-trip to the backend, the selected picture is shown. So far nothing very interesting
$('input').on('change', function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function (event) {
var base64 = event.target.result;
$('<img>').attr('src', base64).appendTo('body');
};
reader.readAsDataURL(file);
});
However, I noticed that on my iPad3 some pictures are shown up-side-down. I found on google about EXIF metadata which is stored in the image (base64) which defines the orientation of the picture. But another thing is, that on my laptop the image are shown normal (with the same pictures of course). Is there any way to prevent/fix this behaviour from happening ? (I want them to show the picture the same way, and if possible I also want them to be shown normal (not up-side-down))

This is not a CSS issue. It's actually an issue with the image. Some browsers interpret the orientation of the image through meta data. Simply open the image in any image editing software and export it. Upload it to your server and let me know if that worked!
EDIT - Reference this URL for a possible solution:
Accessing JPEG EXIF rotation data in JavaScript on the client side

Related

Correctly rotate image taken on android using ImageCapture

I'm using ImageCapture api to capture a screenshoot from a camera of a user device.
The problem is that photos taken on android get rotated incorrectly. They are rotated incorrectly both in the photo preview, before the image is uploaded, and after it is uploaded.
My plan was to read the exif data from a blob that I get from image capture, find orientation in exif and use javascript to rotate the image correctly,
but there is no usable exif data because it isnt jpg.
My code:
function takePhoto(img) {
imageCapture.takePhoto()
.then(blob => {
// EXIF.getData(blob, function() {
// myData = this;
// console.log( myData );
// });
let url = window.URL.createObjectURL(blob);
img.src = url;
console.log( blob );
// stop the camera and hide canavas
stream.getVideoTracks()[0].stop();
$("#webcam").hide();
image = blob;
$("#photo-info").slideDown('slow');
})
.catch(function (error) {
console.log(error);
});
};
takePhoto(document.querySelector('#camera-feed'));
Is there a way to detect if a image is rotated incorrectly when using ImageCapture?
It depends on the device you are using, you should deal with the picture after taken in two steps:
Validate if the photo is rotated.
If necesary rotate the photo.
To validate if the photo is rotated you can use ExifInterface and to rotate you can use a matrix to invert it playing with the bits
You can find more related information and code example at this question
I could not get this working, along with some other problems, so I decided to ditch ImageCapture all together and go with this:
<input type="file" accept="image/*" capture>
This opened the device camera as soon as user clicked on the input button, which is exacly what I needed, but since the taken photo came with exif on android I could correctly rotate it.
For the rotation itself, I used this library

html2canvas , save render canvas as a gif instead of a png?

I'm using html2canvas to save a snapshot from the webcam as an image.
However, it save only in png, I'm trying to save it as a gif, but can not find out how to do this
So far this is my function:
renderCanvasImage: function(){
setTimeout(function () {
// Add image with Quote to Canvas (hidden).
html2canvas($('.snap'), {
onrendered: function (canvas) {
document.body.appendChild(canvas).id = 'hidden';
var canvas = document.getElementById('hidden');
var image = new Image();
//Create a new Image with url
image.src = canvas.toDataURL("image/.png");
// Look at URI only and assign to localStorage
imageURI = image.src;
localStorage.setItem('image', imageURI);
//****TODO better removal*/
$('#cameraContainer, .wrapperInfo').hide();
$('#result a, #result img').fadeOut(100).remove();
$(image).appendTo('#result');
$('#result').fadeIn(200);
//Send Data to DB
tibo.setData();
//PopUp Message
tibo.popupMsg();
}
});
}, 1000);
},
I tried to replace the following:
image.src = canvas.toDataURL("image/.png");
By jpg of gif, but it doesn't change anything.... any tips to make this work will be amazing !!
Thanks a lot !!
You said in the comments above that you've got it working, however I still feel the need to tell you that the supported mime types of toDataUrl depend on the browser.
You can test it here https://jsfiddle.net/v91y0zqr/
Here's a visual example with even more mime types: http://kangax.github.io/jstests/toDataUrl_mime_type_test/
All browsers I've tested (Firefox, Chrome, Opera, IE) did support image/png and image/jpeg
Additionally, Chrome could export image/webp
Additionally, Firefox could export image/bmp
Results may differ for you.
So while in theory canvas.toDataURL("image/gif"); should create a GIF image, the browser may still decide to create a PNG (it's the default fallback).
You can read more about toDataUrl here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

How to encrypt and decrypt image files online?

I'm working on a web application that involves loading images into a canvas object, then manipulating those images beyond recognition. I need to hide the original source image file (a jpeg) so that the user on the client side should not be able to use dev tools to see the original image.
I have tried to encode the images as a base64 and load it via a JSON data file, but even with this method, the inspector tool still shows the original image file (when it is set as the src of my javascript image object). Is there some way that I can encrypt and decrypt the image files, so that the user has no way of seeing the original image (or have it be some garbled image, for example)? Preferably I'd like to do this on the client side, as all my code is client side at the moment. Thanks in advance!
Here is my code for loading the base64 encoded image data via a JSON file:
//LOAD JSON INSTEAD?
$.getJSON( "media/masks.json", function( data ) {
console.log("media/masks.json LOADED");
//loop through data
var cnt = 0;
for (var key in data)
{
if (data.hasOwnProperty(key))
{
// here you have access to
//var id = key;
var imgData = data[key];
//create image object from data
var image = new Image();
image.src = imgData;
console.log('img src: '+ imgData);
var elementId = $scope.masks[cnt].id;
// copy the images to canvases
imagecanvas = document.createElement('CANVAS');
imagecanvas.width = image.width;
imagecanvas.height = image.height;
imagecanvas.getContext('2d').drawImage(image,0,0);
imageCanvases[elementId] = imagecanvas;
}
cnt++;
}
});
This is what I see in the Chrome dev tools Network inspector (exactly what I'm trying to avoid):
I need to hide the original source image file (a jpeg) so that the user on the client side should not be able to use dev tools to see the original image.
That's not possible. There is always a way to get at the image using developer tools. Even if there wasn't, a simple screen capture would defeat whatever measures you put in place.

HTML5/ javascript barcode reader on mobile without manually switching resolution

I am trying to do barcode reading in HTML5/ Javascript on mobile so I can extract the barcode and post to a Ruby on Rails web service.
I am using this code for barcode reading: code by manuels which works fine (You can try out the barcode reader code here) if camera on mobile is set to a very low resolution, not at high resolution though. This method using HTML Media Capture is not ideal as user would have to switch to low resolution manually. I know one can set resolution using GetUserMedia but it's not compatible with many browser/ versions.
I am trying to resize the captured photo using a canvas, based on the canvas code here (not written by myself). The resize works as expect. I then combine the barcode reading code mentioned above in the resize function as below but the barcode reading part doesn't work.
... var interface = new Interface('./bardecode-worker.js');
interface.on_stdout = function(x) { document.getElementById('barcode').appendChild(document.createTextNode('result:
'+x)); }; ...
interface.addData(tempCanvas.toDataURL('image/jpeg'), '/barcode.jpg').then
(
function()
{
interface.run('/barcode.jpg').then
(
function() { console.log(arguments); }
);
}
)
This is manuels' original code below, and in the above code, I am trying to feed the resized image from the canvas into the interface.js instead of a FileReader:
document.getElementById('barcode_file').onchange = function(e) {
var file = e.target.files[0];
var reader = new FileReader();
document.getElementById('barcode').appendChild(document.createTextNode('running...'));
reader.onload = function(ev) {
interface.addData(ev.target.result, '/barcode.jpg').then(function() {
interface.run('/barcode.jpg').then(function() { console.log(arguments); });
})
};
reader.readAsBinaryString(file);
};
Sorry, I am quite new to javascript. Any suggestions? Or is there a better solution?
You might be interested in looking at this program which specializes in providing easier access to hardware on mobile phones.
http://bridgeit.mobi/
It installs a native app on the phone and then lets you open the app from your webpage and then passes back the scan or photo or other item.
They use a javascript library they wrote to open the app and then pass the information back to your webpage.
The library will also open the store page of the program if it is not installed the first time it a user tries to use it.

Create HTML image from data in Javascript variable

I have image data (either JPEG or PNG) in a Javascript variable. How do I display the image in an HTML document? These are very large images and code like this doesn't work because the URI is too long:
// doesn't work because the URI is too long
$('img#target').attr('src', 'data:...');
Using canvas is probably the answer but I cannot figure out how to load it with the image data.
In case you are wondering: no, I cannot just download the image data directly to the img tag. It came from the server encrypted and was decrypted within the browser using Javascript.
Thanks,
-- Art Z.
To use a data URL to draw on a canvas:
var img = new Image;
img.onload = function(){
myCanvasContext.drawImage(img,0,0);
};
img.src = "data:...";
Per this question/answer be sure that you set the onload before the src.
You say that "the URI is too long", but it is not clear what you mean by this. Only IE8 has a 32kB limit on the data URI; for other browsers it should work fine. If you are experiencing an error, please describe it.
It turns out that
$('img#target').attr('src', 'data:...');
does work in all except IE. My problem originated elsewhere.

Categories