The situation is that, I want to open an image in bootstrap popover v2.3.1
And the image is in Base64 format.
On the click of the button [id='imagePopoverButton'], the popover window is opening but the base 64 image is not appearing.
I am sharing the below code snippet, if some one can help me in trouble shooting the same.
<!-- js func, which load Base 64 img format via Ajax -->
function showImagePopover() {
$.ajax({
url : getContextPath()
+ "/app/Application/showImagePopover",
type : 'POST',
async : false,
success : function(jqXHR) {
// In this scope, i have fetched the ajax image, but i am not been able
//to show that up in popover
}
});
}
/***************************************************************/
<!-- Popover function js, html:true -->
$("#imagePopoverButton").popover({
content : showImagePopover(),
html : true,
trigger : 'click',
placement : 'right',
});
/***************************************************************/
<!-- via Clicking of the button, ajax call is suppose to load base64 image in popover -->
<button type="button" class="btn btn-mini btn-primary" id="imagePopoverButton" rel="popover">imagePopover</button>
Add the following below the comments
var image = new Image();
image.src = "data:image/png;base64," + jqXHR;
image.id = "image_id";
image.width = '500';
image.height = '500';
$('#imagePopoverButton').html(image);
Related
This is a knowledge sharing Q&A.
Cropme is a nice JS add-on for cropping and rotating an image using visual sliders. The author provided good documentation, but building a working implementation is not as simple as it should be.
The question I want to answer is this:
I want to allow my website-users to upload their profile image. That image must be exactly 240x292 pixels. The users should be able zoom and rotate their image, then crop it to that specific size and upload it to my website. How can I do all that with cropme?
These are the requires steps:
Show an empty placeholder for the image we want the user to load.
By clicking the "Get Image" button, the user can select an image from its local files.
The selected file is loaded into memory, and presented for editing using 'cropme'. The user can use visual sliders to rotate and zoom in/out
After clicking "Crop", the user is presented with the cropped image, and can decide to save the image or to cancel.
After clicking "Save", the cropped image is uploaded to a PHP server, the modal window is closed, and the placeholder image is replaced with the link to the just-uploaded image.
So how can we do this?
A fully working demo is presented here:
https://codepen.io/ishahak/pen/XWjVzLr
I will explain some of the details, step by step.
Note: usually in my code when you see obj[0], it is simply a conversion from jQuery object into a simple JS object.
1. Showing a placeholder for the image.
We can create a real SVG image on the fly using this code:
getImagePlaceholder: function(width, height, text) {
//based on https://cloudfour.com/thinks/simple-svg-placeholder/
var svg = '\
<svg xmlns="http://www.w3.org/2000/svg" width="{w}" \
height="{h}" viewBox="0 0 {w} {h}">\
<rect fill="#ddd" width="{w}" height="{h}"/>\
<text fill="rgba(0,0,0,0.5)" font-family="sans-serif"\
font-size="30" dy="10.5" font-weight="bold"\
x="50%" y="50%" text-anchor="middle">{t}</text>\
</svg>';
var cleaned = svg
.replace(/{w}/g, width)
.replace(/{h}/g, height)
.replace('{t}', text)
.replace(/[\t\n\r]/gim, '') // Strip newlines and tabs
.replace(/\s\s+/g, ' ') // Condense multiple spaces
.replace(/'/gim, '\\i'); // Normalize quotes
var encoded = encodeURIComponent(cleaned)
.replace(/\(/g, '%28') // Encode brackets
.replace(/\)/g, '%29');
return 'data:image/svg+xml;charset=UTF-8,' + encoded;
}
2. By clicking the "Get Image" button, the user can select an image from its local files.
This process involves an input element of type "file" which has no visible appearance (we set it with the 'd-none' class), and a button element which 'clicks' it to open a dialog:
<button id="btnGetImage" class="btn btn-primary">Get Image</button>
<input class="d-none" type="file" id="fileUpload" accept="image/*" />
And the relevant code:
$('#btnGetImage').on('click', function(){
//force 'change' event even if repeating same file:
$('#fileUpload').prop("value", "");
$('#fileUpload').click();
});
$('#fileUpload').on('change', function(){
CiM.read_file_from_input(/*input elem*/this, function() {
console.log('image src fully loaded');
$('#imgModal-dialog').modal('show');
});
});
When a file is selected, the 'change' event is firing, leading us to read the file into memory.
3. The selected file is loaded into memory, and presented for editing using 'cropme'. The user can use visual sliders to rotate and zoom in/out
Our read_file_from_input mentioned above is implemented like this:
imgHolder: null,
imgHolderCallback: null,
read_file_from_input: function(input, callback) {
if (input.files && input.files[0]) {
imgHolderCallback = callback;
var reader = new FileReader();
if (!CiM.imgHolder) {
CiM.imgHolder = new Image();
CiM.imgHolder.onload = function () {
if (imgHolderCallback) {
imgHolderCallback();
}
}
}
reader.onload = function (e) {
console.log('image data loaded!');
CiM.imgHolder.src = e.target.result; //listen to img:load...
}
reader.readAsDataURL(input.files[0]);
}
else {
console.warn('failed to read file');
}
}
When the FileReader is ready, we set the src for our internal image holder, and wait for the 'load' event, which signals that the img element is ready with the new content.
We listen to that 'load' event, and when triggered we show the modal. A modal in Bootstrap has several events. We listen to the one which signals that the modal is shown, meaning that the width and set and we can plan our Cropme dimensions based on it.
update_options_for_width: function(w) {
var o = CiM.opt, //shortcut
vp_ratio = o.my_final_size.w / o.my_final_size.h,
h, new_vp_w, new_vp_h;
w = Math.floor(w * 0.9);
h = Math.floor(w / o.my_win_ratio);
o.container.width = w;
o.container.height = h;
new_vp_h = 0.6 * h;
new_vp_w = new_vp_h * vp_ratio;
// if we adapted to the height, but it's too wide:
if (new_vp_w > 0.6 * w) {
new_vp_w = 0.6 * w;
new_vp_h = new_vp_w / vp_ratio;
}
new_vp_w = Math.floor(new_vp_w);
new_vp_h = Math.floor(new_vp_h);
o.viewport.height = new_vp_h;
o.viewport.width = new_vp_w;
}
We wait for the size of the modal to be set because cropme must be set with specific viewport dimensions. At the end of our shown.bs.modal handler, we create our Cropme instance.
4. After clicking "Crop", the user is presented with the cropped image, and can decide to save the image or to cancel.
Here is the save-button handler:
$('#imgModal-btnSave').on('click', function(){
uploadImage(croppedImg[0], function(path_to_saved) {
savedImg[0].src = path_to_saved;
$('#imgModal-dialog').modal('hide');
});
});
The uploadImage function goes like this:
uploadImage: function(img, callback){
var imgCanvas = document.createElement("canvas"),
imgContext = imgCanvas.getContext("2d");
// Make sure canvas is as big as the picture (needed??)
imgCanvas.width = img.width;
imgCanvas.height = img.height;
// Draw image into canvas element
imgContext.drawImage(img, 0, 0, img.width, img.height);
var dataURL = imgCanvas.toDataURL();
$.ajax({
type: "POST",
url: "save-img.php", // see code at the bottom
data: {
imgBase64: dataURL
}
}).done(function(resp) {
if (resp.startsWith('nok')) {
console.warn('got save error:', resp);
} else {
if (callback) callback(resp);
}
});
}
It is matched with a simple PHP script which appears at the end of the HTML in the codepen. I think this answer went too long, so I'll finish here.
Good luck - have fun :)
With Dropzone.js, I am trying to get image height and width with createImageThumbnails = false. To be more precise, I do not need thumbnails to be created while dropping images because the process becomes slow specially when I drop many images at once. I just need to scan height and width of all images that are dropped and save them into a database. But the problem is, when I turn off thumbnail creation, dropzone does not provide image height and width. As per documentation, image height and width are provided after the thumbnail event is triggered. So, quite the opposite to what I need. So as a solution, I would like to be able to get image height and width info as soon as images are dropped into dropzone and there should be no delay for creating thumbnail. Please advise if there is a way out of it.
HTML
<div id="dropzone">
<form class="dropzone" id = "upload-widget" action = "/demo">
</form>
</div>
JS
jQuery(document).ready(function($)
{
var images = Array();
var item = [];
Dropzone.options.uploadWidget = {
autoProcessQueue: false,
acceptedFiles: 'image/*',
previewTemplate: '<div class="dz-filename"><span data-dz-name></span></div>',
createImageThumbnails: false,
init: function() {
this.on("addedfile", function(file)
{
height = file.height;
width = file.width;
item = {Name : file.name, Size:file.size, Height:file.height, Width:file.width};
images.push(item);
});
}
};
});
You could try working with the accept function, along with FileReader(), and the Image() constructor.
Dropzone.options.uploadWidget = {
autoProcessQueue: false,
acceptedFiles: 'image/*',
previewTemplate: '<div class="dz-filename"><span data-dz-name></span></div>',
createImageThumbnails: false,
accept: function(file, done) {
// FileReader() asynchronously reads the contents of files (or raw data buffers) stored on the user's computer.
var reader = new FileReader();
reader.onload = (function(entry) {
// The Image() constructor creates a new HTMLImageElement instance.
var image = new Image();
image.src = entry.target.result;
image.onload = function() {
console.log(this.width);
console.log(this.height);
};
});
reader.readAsDataURL(file);
done();
}
}
I'm integrating Adobe Creative SDK WEB to my angularjs website.
I have followed the "Image Editor UI" guide from official Adobe website
And also a this example using angularjs:
https:// github.com/CreativeSDK/web-getting-started-samples/tree/master/image-editor-ui/image-editor-ui-angular-express>
In both cases I tried with dynamic and hard coded id and image src.
** This is working **
When I click the "edit" link, editor opens fine and start loading the image.
While loading, the image size is exactly the same as my placeholder size.
Screen capture of my table with image and link https://ibb.co/kZ5ama
** End this is working **
The problem I'm getting is this:
After the photo is loaded, the size shrinks and goes to the top left corner.
Also when I try to draw on top of it, I have to start by clicking inside the small photo and continue as if the size of the photo is the entire screen.
Screen capture of the editor here, look at the end of the red stroke and my cursor position: https://ibb.co/iYJECF
Here is my edit link
<a href="javascript:;" id="edit-image-button" class="btn btn-primary btn-block button-panel" ng-click="launchEditor('image_'+$index, item2)">
Edit Image
</a>
My image placeholder
<a ng-click="openLightboxModal(name2,'notsynced')" >
<img id="image_{{$index}}"class="img-responsive" src="{{item2}}" alt="">
</a>
$scope.getImageEditor = function() {
$scope.imageEditor = new Aviary.Feather({
apiKey: "My id is here",
onSave: function(imageID, newURL) {
$scope.currentImageSrc = newURL;
$scope.imageEditor.close();
$scope.$digest();
console.log(newURL);
},
onError: function(errorObj) {
console.log(errorObj.code);
console.log(errorObj.message);
console.log(errorObj.args);
}
});
}
$scope.launchEditor = function(imageId, imageURL) {
$scope.originalImageSrc = imageURL;
$scope.currentImageSrc = $scope.originalImageSrc;
console.log(imageId);
console.log(imageURL);
$scope.imageId = imageId;
var terms = /^https?:///;
var isUrl = $scope.currentImageSrc.match(terms);
if (isUrl) {
$scope.imageEditor.launch({
image: $scope.imageId,
url: $scope.currentImageSrc
});
}
else {
$scope.imageEditor.launch({
image: $scope.imageId
});
}
}
After removing all CSS and inspecting element by element, I have found the culprit. It was a CSS conflict, which made all CANVAS element to have a fixed height of 100px.
Thanks for reading.
I have input with url, and 'preview' button.
When I click 'preview' it inserts image from this url, before 'submit' button.
$('#preview').click(function() {
var image_url = $('#event_remote_flyer_url').val();
var image_tag = $('<img class="preview">');
image_tag.attr('src',image_url)
$('input[name="commit"]').before(image_tag);
});
Now I want to add cropper plugin for this image. (https://github.com/fengyuanchen/cropper)
Docs say I should use it like this:
$('img.preview').cropper({
aspectRatio: 16 / 9,
crop: function(e) {
// Output the result data for cropping image.
console.log(e.x);
console.log(e.y);
console.log(e.width);
console.log(e.height);
console.log(e.rotate);
console.log(e.scaleX);
console.log(e.scaleY);
}
});
It doesn't work. As I understand javascript is not waiting with this cropper function and runs it when img.preview is not inserted yet. How can I fix this?
You need to attach it when creating img.preview elements and your understanding is spot on.
$('#preview').click(function() {
var image_url = $('#event_remote_flyer_url').val();
var image_tag = $('<img class="preview">');
image_tag.attr('src', image_url)
//Atach Cropper
image_tag.cropper({
aspectRatio: 16 / 9,
crop: function(e) {}
});
//Append
$('input[name="commit"]').before(image_tag);
});
I have a temporary image which i want to copy to gallery using javascript(phonegap).
Any help?
function save() {
var image = document.getElementById("tempImg");
//upload image to gallery of mobile . But how??
}
My image contains photo and text together...
i just want to arrange all div data including image inside div with some text on it and save it as an full image with any format .jpg,png etc in javascript.
I referred this link but that is for canvas to image but i want div to image .
Canvas to PhotoLibrary [Phonegap]
You might want to check out this url: http://html2canvas.hertzen.com/.
Using this script, you can convert your div into a canvas, then use the "Canvas to PhotoLibrary [Phonegap]" to do the rest.
Your code would look something like this:
function save() {
var image = document.getElementById("tempImg");
html2canvas(image, {
onrendered: function(canvas) {
// use "Canvas to PhotoLibrary [Phonegap]" on the canvas variable
}
});
}
you save this using session storage(or)local storage
save:
var z1,z2,z3;
function save() {
var a=$("#theme1_text").val();
var b=$("#image_div").css("background-image");
var c=$("#background_theme1").css("background-image");
sessionStorage.z1=a;
sessionStorage.z2=b;
sessionStorage.z3=c;
};
view:
function view() {
$("#theme1_text").val(sessionStorage.z1);
$("#image_div").css("background-image",sessionStorage.z2);
$("#background_theme1").css("background-image",sessionStorage.z3);
};