Error loading image through localforage blob on ios - javascript

I am grabbing camera image on an ios device through Cordova camera API and then saving it through localforage. However, it seems that the resource is not being loaded since clicking on the blob under Resources tag of Safari Web Inspector shows An error occured while trying to load resources error, and the image renders as 20x20 white background instead of photo. Here is my HTML wrapper around Cordova Camera API:
<head>
<title>Capture Photo</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="js/camera.js"></script>
<script type="text/javascript" charset="utf-u" src="js/localforage.js"></script>
<script type="text/javascript">
function savePhoto(contents){
localforage.setItem('photo', contents, function(img) {
// This will be a valid blob URI for an <img> tag.
var blob = new Blob([img], { type: "image/jpeg" } );
var imageURI = window.URL.createObjectURL(blob);
console.log(imageURI);
var newImg = document.createElement("img");
newImg.src=imageURI;
// add the newly created element and its content into the DOM
var currentDiv = document.getElementById("div1");
document.body.insertBefore(newImg, currentDiv);
});
console.log(contents.byteLength);
}
function grabPhoto(){
capturePhotoEdit(savePhoto,function(e){console.log(e);});
}
</script>
</head>
<body>
<button onclick="grabPhoto();">Capture Photo</button> <br>
<div id="div1"> </div>
</body>
</html>
We use savePhoto to save down the image grabbed from the camera (in js/camera.js). Console logging of blob prints out stuff like blob:null/916d1852-c8c5-4b3b-ac8c-86b6c71d0e86.
I will very much appreciate pointers on what I am doing wrong here with image rendering.

Fixed now by switching to "Promise" style API. Somehow, it doesn't work for async callback API version. Fixed JS code below:
function savePhoto(contents){
localforage.setItem('photo', contents).then(function(image) {
// This will be a valid blob URI for an <img> tag.
var blob = new Blob([image],{ type:"image/jpeg" });
console.log('size=' + blob.size);
console.log('type=' + blob.type);
var imageURI = window.URL.createObjectURL(blob);
var newImg = document.createElement("img");
newImg.src=imageURI;
newImg.onload = function() {
URL.revokeObjectURL(imageUrI);
};
var currentDiv = document.getElementById("div1");
document.body.insertBefore(newImg, currentDiv);
}).catch(function(err) {
// This code runs if there were any errors
console.log(err);
});
}
function grabPhoto(){
capturePhotoEdit(savePhoto,function(e){console.log(e);});
}

Related

How can I load pdf with base64 using mozilla pdf js viewer

I am using mozilla pdf js viewer to render pdf on my page.
I never used this third party dependency and I am struggling with basic things because there is very small amount of documentation how things works.
I am getting base 64 from API and I need to show this base 64 on my page.
I found some examples on their page but they are not working
https://mozilla.github.io/pdf.js/examples/
I tried
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'Hello, world!' example</title>
</head>
<link href="index.css" rel="stylesheet" />
<body>
<h1>'Hello, world!' example</h1>
<h1>PDF.js 'Hello, world!' example</h1>
<canvas id="the-canvas"></canvas>
<script src="index.js"></script>
<script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>
</body>
</html>
#the-canvas {
border: 1px solid black;
direction: ltr;
}
// atob() is used to convert base64 encoded PDF to binary-like data.
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
// Base64_encoding_and_decoding.)
var pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];
// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
// Using DocumentInitParameters object to load binary data.
var loadingTask = pdfjsLib.getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
console.log('PDF loaded');
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
var scale = 1.5;
var viewport = page.getViewport({scale: scale});
// Prepare canvas using PDF page dimensions
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
console.log('Page rendered');
});
});
}, function (reason) {
// PDF loading error
console.error(reason);
});
but I get error Uncaught TypeError: Cannot read properties of undefined (reading 'GlobalWorkerOptions')
I have downloaded pdfjs-dist locally in my project I have the web and build folders.
How can i U se the viewer html from web folder and load files on my page ?
I also tried this
https://www.youtube.com/watch?v=TstpR_gGb-4
I also need to load the pdf in iframe

'No function was found that matched the signature provided' with drag and drop

I am attempting to make it so that when you drag an image from your files or the internet into the drop area it makes an image on the page take the SRC of that image. This seems like it would be easy, but I have looked all over the internet
and have been unable to figure this out. Chrome throws the error:
'No function was found that matched the signature provided'.
<!doctype html>
<html>
<head>
<script>
function dropHandler(ev) {
ev.preventDefault();
img = new Image();
fileTransferred = ev.dataTransfer.items[0];
img.src = window.URL.createObjectURL(ev.dataTransfer.items[0]);
ev.dataTransfer.items.clear();
ev.dataTransfer.clearData();
window.URL.revokeObjectURL(img.src);
}
function dragOverHandler(ev) {
ev.preventDefault();
}
</script>
</head>
<body>
<div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);">
<p>Drag a picture here.</p>
</div>
</body>
</html>
Why doesn't this work?
After a bit of checking, I found out that you should make it behave as a file, not an item. Demo that shows this is here.
JS
function dropHandler(ev) {
ev.preventDefault();
img = new Image();
fileTransferred = ev.dataTransfer.files[0];
img.src = window.URL.createObjectURL(fileTransferred);
ev.dataTransfer.items.clear();
ev.dataTransfer.clearData();
window.URL.revokeObjectURL(img.src);
alert(img.src);
}
function dragOverHandler(ev) {
ev.preventDefault();
}

IE Copy Canvas in Pop-Up Window DOM Exception: TYPE_MISMATCH_ERR (17)

I don't know if there is a work around for this IE9 issue I ran into, but here's what I'm trying to do. I have an image in a canvas on my page. I want to copy this canvas image to another canvas, but in a pop-up window I create. What I'm encountering in this experiment is I can copy the canvas image into another dynamically created canvas on the same page, no problem. But when I try to do it in a pop-up window, IE gives me a DOM Exception: TYPE_MISMATCH_ERR (17). Sadly, this seems to be an IE thing, because I ran my same code in Chrome, and it worked...
So here's my code. You'll need to provide your own image though, I used a simple 640x480 jpeg file. You'll also need the console open, since I'm doing a console.error. I also tried this code as a file and running from localhost on my local IIS.
<!DOCTYPE html>
<html>
<head>
<title>Canvas Copy Test</title>
<style>
#mainSrc {
border:1px solid red;
}
#dest01 {
width:640px;
height:480px;
border:1px solid blue;
}
</style>
<script>
var destWin; // Destination Window
window.onload=function()
{
var testImg = new Image();
testImg.src = "me.jpg";
testImg.onload = function()
{
var mainCanvas = document.getElementById("mainSrc");
var mainCtx = mainCanvas.getContext("2d");
mainCtx.drawImage(testImg,0,0);
}
var copyBtn = document.getElementById("copyBtn");
var copyWinBtn = document.getElementById("copy2WinBtn");
copyBtn.addEventListener("click",copyImage,false);
copyWinBtn.addEventListener("click",copy2Win,false);
}
// Copy Canvas Image to Another on the same page.
function copyImage()
{
var mainCanvas = document.getElementById("mainSrc");
var destCanvas = document.createElement("canvas");
var destDiv = document.getElementById("dest01");
destCanvas.width = mainCanvas.width;
destCanvas.height = mainCanvas.height;
var dCtx = destCanvas.getContext("2d");
dCtx.drawImage(mainCanvas,0,0);
destDiv.appendChild(destCanvas);
}
// Copy Canvas to Popup Window
function copy2Win()
{
var mainCanvas = document.getElementById("mainSrc");
try {
destWin = window.open("","destWin");
var destWinDoc = destWin.document;
var destWinHTML = "<!DOCTYPE html><html><head><title>POPUP</title><body><div id='destWinDiv' style='width:640px; height:480px; border:1px solid red'></div></body></html>";
destWinDoc.write(destWinHTML);
var destCanvas = destWinDoc.createElement("canvas");
var destDiv = destWinDoc.getElementById("destWinDiv");
destCanvas.width = mainCanvas.width;
destCanvas.height = mainCanvas.height;
var dCtx = destCanvas.getContext("2d");
dCtx.drawImage(mainCanvas,0,0);
destDiv.appendChild(destCanvas);
}
catch (err)
{
console.error(err);
}
}
</script>
</head>
<body>
<canvas id="mainSrc" width="640" height="480"></canvas>
<p>
<input type="button" name="Copy" value="Copy" id="copyBtn" />
<input type="button" name="Copy2Win" value="Copy To New Window" id="copy2WinBtn" />
</p>
<div id="dest01"></div>
</body>
</html>
Well, after playing around a little more, I figured out that the tag can actually take in a base64 encoded image from the canvas toDataURL() and display it... So I was able to make this modification in my above copy2Win function to be this:
function copy2Win()
{
var mainCanvas = document.getElementById("mainSrc");
destWin = window.open("","destWin");
var destWinDoc = destWin.document;
var destWinHTML = "<!DOCTYPE html><html><head><title>POPUP</title><body><div id='destWin' style='width:640px; height:480px; border:1px solid red'><img src='" + mainCanvas.toDataURL() + "' alt='Copy!' /></div></body></html>";
destWinDoc.write(destWinHTML);
}
The thing to note is I'm writing out the img tag's src to be the canvas.toDataURL(), and this works. IE doesn't complain about this. Although the data isn't into another canvas, I'm able to get what I need, which is my image data pulled from my canvas and displayed in a new window. Interestingly, if you look at the generated source code the image is actually shown as the base64 encoded data in the src, so it seems the browser is decoding the src data for display; interesting.

Getting IE8 compatibility with EaselJS and ExplorerCanvas

I am using EaselJS and want to allow for backwards compatibility with ExplorerCanvas.
This should be possible using the following code (see here):
createjs.createCanvas = function () { ... return canvas implementation here ... }
However, If I put an alert in this function and run the code, the function is never run.
How do I go about getting this to work?
Edit:
Here is a simplified example of the code I am using:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<script src='/Scripts/jquery-1.7.1.js'></script>
<script src="/Scripts/excanvas/excanvas.compiled.js"></script>
<script src="/Scripts/easeljs/lib/easeljs-0.5.0.min.js"></script>
<script src='/Scripts/core/jquery.mousewheel.js'></script>
<style>
canvas
{
border: 1px solid #ccc;
}
</style>
<script type='text/javascript'>
$(document).ready(function () {
// Variables
var img;
var stage;
var bmp;
// Bindings
$('#load').click(function () { initialize() }); // DELETE
// Functions
function initialize() {
img = new Image();
img.onload = imageLoadedEvent;
img.src = '/Scripts/viewer/June.jpg';
}
function imageLoadedEvent() {
var canvasElement = generateContext('testCanvas', 400, 400);
stage = new createjs.Stage('testCanvas');
bmp = new createjs.Bitmap(img);
stage.autoClear = true;
stage.addChild(bmp);
stage.update();
}
function generateContext(canvasID, width, height) {
var canvasElement = document.createElement('canvas');
if (typeof (G_vmlCanvasManager) != 'undefined')
canvasElement = G_vmlCanvasManager.initElement(canvasElement);
canvasElement.setAttribute("width", width);
canvasElement.setAttribute("height", height);
canvasElement.setAttribute("id", canvasID);
document.getElementById('viewer').appendChild(canvasElement);
}
});
</script>
</head>
<body>
<div id='viewer'>
<button id='load'>load</button>
</div>
</body>
</html>
This example will run in Chrome and IE9 as a native canvas element is created and used. However in IE8 it fails.
I ran across this issue as well, trying to get ExCanvas to play nice with EaselJS. Here is how I got it working. Hope this helps with your image issue.
Get the source code for EaselJS : https://github.com/gskinner/EaselJS.git. This will get all the javascript files separated out into their own parts.
Copy all those files over to a "easel" folder in your project directory.
The order in which the files are loaded is important, so see below on how to do it.
EaselJS has an option to override the createCanvas method, which is required to use ExCanvas with it. This happens after loading the SpriteSheet.js file, and BEFORE loading Graphics.js, DisplayObject.js, Container.js, etc. In the code below, I used jQuery to load the rest of the js files that easelJs needed. This all happens in the $(document).ready() function.
If done correctly, you should see a 700 x 700 canvas with a red line from top left to bottom right in IE (tested in 8).
head>
<!--
Load ExCanvas first, and jquery
-->
<script type='text/javascript' src='./javascript/excanvas.js'></script>
<script type='text/javascript' src='./javascript/jquery-1.8.2.min.js'></script>
<!--
Have to load Easel js files in a certain order, and override the createCanvas
function in order for it to work in < IE9.
-->
<script type='text/javascript' src='./javascript/easel/UID.js'></script>
<script type='text/javascript' src='./javascript/easel/Ticker.js'></script>
<script type='text/javascript' src='./javascript/easel/EventDispatcher.js'></script>
<script type='text/javascript' src='./javascript/easel/MouseEvent.js'></script>
<script type='text/javascript' src='./javascript/easel/Matrix2D.js'></script>
<script type='text/javascript' src='./javascript/easel/Point.js'></script>
<script type='text/javascript' src='./javascript/easel/Rectangle.js'></script>
<script type='text/javascript' src='./javascript/easel/Shadow.js'></script>
<script type='text/javascript' src='./javascript/easel/SpriteSheet.js'></script>
<script type='text/javascript'>
var canvas, stage;
createjs.createCanvas = function () { return getCanvas(); };
function getCanvas() {
// This is needed, otherwise it will keep adding canvases, but it only use the last one it creates.
canvas = document.getElementById("myCanvas");
if (canvas != null) {
document.getElementById("container").removeChild(canvas);
}
canvas = document.createElement("canvas");
document.getElementById("container").appendChild(canvas);
if (typeof (G_vmlCanvasManager) != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
canvas.setAttribute("height", "700");
canvas.setAttribute("width", "700");
canvas.setAttribute("style", "height:700px; width:700px;");
canvas.setAttribute("id", "myCanvas");
}
return canvas;
}
</script>
<script type="text/javascript">
$(document).ready(function () {
loadOtherScripts();
stage = new createjs.Stage(canvas);
// Draw a red line from top left to bottom right
var line = new createjs.Shape();
line.graphics.clear();
line.graphics.setStrokeStyle(2);
line.graphics.beginStroke("#FF0000");
line.graphics.moveTo(0, 0);
line.graphics.lineTo(700, 700);
stage.addChild(line);
stage.update();
});
function loadOtherScripts() {
var jsAr = new Array(13);
jsAr[0] = './javascript/easel/Graphics.js';
jsAr[1] = './javascript/easel/DisplayObject.js';
jsAr[2] = './javascript/easel/Container.js';
jsAr[3] = './javascript/easel/Stage.js';
jsAr[4] = './javascript/easel/Bitmap.js';
jsAr[5] = './javascript/easel/BitmapAnimation.js';
jsAr[6] = './javascript/easel/Shape.js';
jsAr[7] = './javascript/easel/Text.js';
jsAr[8] = './javascript/easel/SpriteSheetUtils.js';
jsAr[9] = './javascript/easel/SpriteSheetBuilder.js';
jsAr[10] = './javascript/easel/DOMElement.js';
jsAr[11] = './javascript/easel/Filter.js';
jsAr[12] = './javascript/easel/Touch.js';
for (var i = 0; i < jsAr.length; i++) {
var js = jsAr[i];
$.ajax({
async: false,
type: "GET",
url: js,
data: null,
dataType: 'script'
});
}
}
</head>
<body>
<div id="container"></div>
</body>
</html>
You should instantiate the quasi canvas element by making reference to the original canvas source as provided on the project page example:
<head>
<!--[if lt IE 9]><script src="excanvas.js"></script><![endif]-->
</head>
var el = document.createElement('canvas');
G_vmlCanvasManager.initElement(el);
var ctx = el.getContext('2d');
EDIT:
After further investigation i came to the following conclusions!
There are multiple reasons for not being able to include the image into the canvas:
1st probably there is a bug in the excanvas code for not being able to mimic the native canvas features. I used with more success the modified sancha code, which you can obtain here: http://dev.sencha.com/playpen/tm/excanvas-patch/excanvas-modified.js. See live example here: http://jsfiddle.net/aDHKm/ (try it on IE).
2nd before Easeljs initialize the core objects and classes first is searching for the canvas element existence. Because IE < 9 doesn't have implemented the canvas it's obvious that easeljs core graphics API's can not be instantiated. I think these are the two main reasons that your code is not working.
My suggestion is to try to remake the code without the easeljs. I made a fiddle with the necessary modification to show you how can be done without easeljs: http://jsfiddle.net/xdXrw/. I don't know if it's absolute imperative for you to use easeljs, but certainly it has some limitations in terms of IE8 hacked canvas.

how to validate image size and dimensions before saving image in database

I am using ASP.NET C# 4.0, my web form consist of input type file to upload images.
i need to validate the image on client side, before saving it to my SQL database
since i am using input type= file to upload images, i do not want to post back the page for validating the image size, dimensions.
Needs your assistance
Thanks
you can do something like this...
You can do this on browsers that support the new File API from the W3C, using the readAsDataURL function on the FileReader interface and assigning the data URL to the src of an img (after which you can read the height and width of the image). Currently Firefox 3.6 supports the File API, and I think Chrome and Safari either already do or are about to.
So your logic during the transitional phase would be something like this:
Detect whether the browser supports the File API (which is easy: if (typeof window.FileReader === 'function')).
If it does, great, read the data locally and insert it in an image to find the dimensions.
If not, upload the file to the server (probably submitting the form from an iframe to avoid leaving the page), and then poll the server asking how big the image is (or just asking for the uploaded image, if you prefer).
Edit I've been meaning to work up an example of the File API for some time; here's one:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Show Image Dimensions Locally</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript'>
function loadImage() {
var input, file, fr, img;
if (typeof window.FileReader !== 'function') {
write("The file API isn't supported on this browser yet.");
return;
}
input = document.getElementById('imgfile');
if (!input) {
write("Um, couldn't find the imgfile element.");
}
else if (!input.files) {
write("This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
write("Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = createImage;
fr.readAsDataURL(file);
}
function createImage() {
img = document.createElement('img');
img.onload = imageLoaded;
img.style.display = 'none'; // If you don't want it showing
img.src = fr.result;
document.body.appendChild(img);
}
function imageLoaded() {
write(img.width + "x" + img.height);
// This next bit removes the image, which is obviously optional -- perhaps you want
// to do something with it!
img.parentNode.removeChild(img);
img = undefined;
}
function write(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
}
</script>
</head>
<body>
<form action='#' onsubmit="return false;">
<input type='file' id='imgfile'>
<input type='button' id='btnLoad' value='Load' onclick='loadImage();'>
</form>
</body>
</html>
Works great on Firefox 3.6. I avoided using any library there, so apologies for the attribute (DOM0) style event handlers and such.
function getImgSize(imgSrc) {
var newImg = new Image();
newImg.onload = function() {
var height = newImg.height;
var width = newImg.width;
alert ('The image size is '+width+'*'+height);
}
newImg.src = imgSrc; // this must be done AFTER setting onload
}

Categories

Resources