Ti.Media.openPhotoGallery({
success:function(event) {
attch = event.media;
},
cancel:function(){
console.log("error!");
}
});
How can I know the weight of attch? and if is possible, the name of file in gallery.
As is mentioned in the documenation, method success will return an object that contain property media which is image/video in Blob format. If you want to know width of an image do this:
Ti.Media.openPhotoGallery({
success: function(event) {
var image = event.media;
console.log(image.width);
console.log(image.size); // image size in bytes
}
});
Related
I am solving a problem about rotating large photos.
The photo only rotates when resizeWidth is used.
Without using resizeWidth the photo will be uploaded correctly.
Resize photo is used to save space, because nowadays photos are 10MB and more.
Can the photo rotation problem be solved?
Alternatively, how do you deal with resizing?
Thanks a lot
Dropzone.options.frmFormAddFotoPred = {
maxFilesize: 15,
addRemoveLinks: true,
dictResponseError: 'Server not Configured',
resizeWidth: 1200,
acceptedFiles: ".png,.jpg,.jpeg",
init: function () {
var self = this;
this.on('complete', function () {
if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0) {
location.reload();
}
});
self.options.addRemoveLinks = false;
}
};
I have added intervention/image package to convert image format in laravel.
image converted successfully but after uploading image quality was so bad.
Original Image
Uploaded Image
$img =(string) Image::make($image['base64'])
->resize(500, 500)->encode('jpg',100);;
$img = base64_encode($img);
To convert Heic image you have to use imagick, can you use this instead
This is how to install https://ourcodeworld.com/articles/read/645/how-to-install-imagick-for-php-7-in-ubuntu-16-04
try {
$image = new \Imagick();
$image->readImageBlob($image['base64']));
$image->setImageFormat("jpeg");
$image->setImageCompressionQuality(100);
$image->writeImage($targetdir.$uid.".jpg");
}
catch (\ImagickException $ex) {
/**#var \Exception $ex */
return new JSONResponse(["error" => "Imagick failed to convert the images, check if you fulfill all requirements." , "details" => $ex->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR);
}
A bit late, but I had the same problem.
I managed to do it with the heic2any js library (https://github.com/alexcorvi/heic2any/blob/master/docs/getting-started.md)
I converted the picture on client side, then gave it to the input in client side.
Server is seeing it as it was originally uploaded as jpg.
function convertHeicToJpg(input)
{
var fileName = $(input).val();
var fileNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
if(fileNameExt == "heic") {
var blob = $(input)[0].files[0]; //ev.target.files[0];
heic2any({
blob: blob,
toType: "image/jpg",
})
.then(function (resultBlob) {
var url = URL.createObjectURL(resultBlob);
$(input).parent().find(".upload-file").css("background-image", "url("+url+")"); //previewing the uploaded picture
//adding converted picture to the original <input type="file">
let fileInputElement = $(input)[0];
let container = new DataTransfer();
let file = new File([resultBlob], "heic"+".jpg",{type:"image/jpeg", lastModified:new Date().getTime()});
container.items.add(file);
fileInputElement.files = container.files;
console.log("added");
})
.catch(function (x) {
console.log(x.code);
console.log(x.message);
});
}
}
$("#input").change(function() {
convertHeicToJpg(this);
});
What I am doing is converting the heic picture to jpg, then previewing it.
After that I add it to the original input. Server side will consider it as an uploaded jpg.
Some delay can appear while converting, therefore I placed a loader gif while uploading.
The heic2any js library helped me accomplish this (https://github.com/alexcorvi/heic2any/blob/master/docs/getting-started.md)
On the client side, I converted the picture, then gave it to the server input. The server sees it as it was originally uploaded as PNG.
$('#files').on('change' , function(){
var total_file=document.getElementById("files").files.length;
for(var i=0;i<total_file;i++)
{
files = event.target.files[i];
var fileName = files.name;
var fileNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
objURL = URL.createObjectURL(event.target.files[i]);
if(fileNameExt == "heic") {
objURL = await convertHeicToJpg(input , i);
}
})
async function convertHeicToJpg(input , i)
{
var blobfile = $(input)[0].files[i]; //ev.target.files[0];
let blobURL = URL.createObjectURL(blobfile);
// convert "fetch" the new blob url
let blobRes = await fetch(blobURL)
// convert response to blob
let blob = await blobRes.blob()
// convert to PNG - response is blob
let resultBlob = await heic2any({ blob })
console.log(resultBlob)
var url = URL.createObjectURL(resultBlob);
let fileInputElement = $(input)[0];
let container = new DataTransfer();
let file = new File([resultBlob], "heic"+".png",{type:"image/png", lastModified:new Date().getTime()});
container.items.add(file);
fileInputElement.files[0] = container.files;
uploadFile(container.files);
console.log("added");
console.log(url);
return url ;
}
function uploadFile(files)
{
console.log(files);
var error = '';
var form_data = new FormData();
for(var count = 0; count<files.length; count++)
{
var name = files[count].name;
var extension = name.split('.').pop().toLowerCase();
form_data.append("files[]", files[count]);
}
$.ajax({
url:"<?php echo base_url(); ?>Property/upload",
method:"POST",
data:form_data,
contentType:false,
cache:false,
processData:false,
dataType:'JSON',
beforeSend:function(){
//..processing
},
success:function(data)
{
alert('image uploade')
}
})
}
Normally to make colorbox adjust it's size to the content I use this snippet:
$('#colorbox').colorbox({
onComplete: function () {
$(this).colorbox.resize();
}
});
But this time it does not work, when I try the same thing in an ajax function, after the success response:
$.ajax({
data:number,
dataType: "json",
type:"POST",
url : "payment/request1",
cache: false,
success: function (response) {
console.log(response);
if(response === true){
$.colorbox({html:'<div id="paymentblock"><div><h2 style="color:#444;">Open app in your phone</h2></div><div style="text-align:center;"><p>Payment with '+number+'</p><img src="/images/giphy.gif"></div>'});
$('#edit-commerce-payment-payment-details-number').css('background','#fff').val('');
$('#colorbox').colorbox({
onComplete: function () {
$(this).colorbox.resize();
}
});
}else{
$.colorbox({html:'<div id="paymentblock"><div><h2 style="color:#444;">An error occurred</h2></div><div style="text-align:center;"><p>Kontakta oss.</p></div>'});
$('#colorbox').colorbox({
onComplete: function () {
$(this).colorbox.resize();
}
});
}
}
});
The result is that the colorbox opens with a too small size and don't resize to fit the content. What am I doing wrong?
I created a custom function to resize the colorbox after loading content, after resizing the browser window or, on mobile, after an orientation change that also effectively changes the browser window width.
Modern web design has to deal with widely varying browser widths, especially with so many users on cell phones and tablets, so the content you are loading should be responsive, from about a 320 pixel width on up. Then, let the colorbox size be determined by the available browser width as well as a maximum reasonable size for aesthetic reasons.
This goes in a javascript file included at the bottom of each page:
/* Colorbox resize function */
var resizeTimer;
var resizeColorBox = function() {
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
if ($("#cboxOverlay").is(":visible")) {
$.colorbox.resize({maxWidth:"400px",width:"95%"});
}
}, 300);
};
// Resize Colorbox when resizing window or changing mobile device orientation
$(window).resize(resizeColorBox);
window.addEventListener("orientationchange", resizeColorBox, false);
Then, the colorbox function itself has a few parameters that need to be set correctly. Note that I have closebutton set to false because my HTML content includes a close button that calls the colorbox close function.
$.colorbox({
width:"95%",
maxWidth:400,
maxHeight:"95%",
speed:300,
closeButton:false,
onComplete : function() {
$(this).colorbox.resize({width:"95%",maxWidth:400});
$(window).trigger("resize");
},
html:'Your HTML Here'
});
So, your code need only call the resizeColorBox() function after loading AJAX content and you should be good to go. Plus, it handles other resize situations.
[Edit] If you REALLY need to resize to the width of inner content, then the resize function should first get the width of the container div of the inner content, then resize to that width (possibly plus the width of colorbox padding, etc). In that case, the resize function would be more along the lines of:
var resizeColorBox = function() {
var w = $('content_container').width() + padding_w;
var h = $('content-container').height() + padding_h;
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
if ($("#cboxOverlay").is(":visible")) {
$.colorbox.resize({width:w, height:h});
}
}, 300);
};
Just had this same problem. I dealt with this issue by calling the resize method from inside of page being requested. (May not be possible for you)
Inside the page being called:
<script>
// This resize doesn't respect the maxHeight set when initializing
// So we calculate again, for this example 80%
var maxHeight = parent.innerHeight * 0.8
document.addEventListener('DOMContentLoaded', function(event) {
// Get document height after loaded
var documentHeight = document.documentElement.scrollHeight
// Resize
parent.$.colorbox.resize({
innerHeight: Math.min(documentHeight, maxHeight),
})
})
</script>
Hope this helps someone in the future (or myself if I forget).
This is a follow up question to
How to drop texts and images on a canvas? (Firefox 41.0.1)
I simply can't find out how to access the image data of the image I dropped onto the canvas. I tried things like data = event.dataTransfer.getData("image"), but that all doesn't work.
function addDragNDropToCanvas() {
document.getElementById('canvas').addEventListener("dragover", function(event) { event.preventDefault();}, false);
//handle the drop
document.getElementById('canvas').addEventListener("drop", function(event) {
event.preventDefault();
console.log('something is dropped on the object with id: ' + event.target.id);
// var directData=event.dataTransfer.getData("image");
console.log(event);
}, false);
}
There surely is the image-data somewhere incorporated in the drop-event data? Isn't it???
(The image doesn't have an own id-attribute.)
Your user might do one (or both) of these two drags:
Drag an img element from your webpage onto the canvas, or
Drag an image file from your local drive onto the canvas.
If the image is being dragged from your webpage:
Listen for the dragover, drop, and optionally the dragenter events.
When handling all 3 events, tell the browser you're handling the event with event.preventDefault and optionally event.stopPropagation.
In the drop handler, get event.dataTransfer.getData('text/plain') which fetches the.src` of the image that was dropped.
Create a new Image() object using the .src and drawImage to the canvas.
If the image is being dragged from your local drive:
1 & 2. Listen & handle the same events as in the webpage code.
Fetch the local image file(s) that the user dropped which have been placed in event.dataTransfer.files.
Create a FileReader and read each image file. The FileReader.readAsDataURL method will return an image URL that you can use as a .src for an Image object.
drawImage each new image to the canvas.
Here's example code that allows both:
window.onload=function(){
// canvas related vars
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// dropZone event handlers
var dropZone=document.getElementById("canvas");
dropZone.addEventListener("dragenter", handleDragEnter, false);
dropZone.addEventListener("dragover", handleDragOver, false);
dropZone.addEventListener("drop", handleDrop, false);
//
function handleDragEnter(e){e.stopPropagation(); e.preventDefault();}
//
function handleDragOver(e){e.stopPropagation(); e.preventDefault();}
//
function handleDrop(e){
e.stopPropagation();
e.preventDefault();
//
var url=e.dataTransfer.getData('text/plain');
// for img elements, url is the img src so
// create an Image Object & draw to canvas
if(url){
var img=new Image();
img.onload=function(){ctx.drawImage(this,0,0);}
img.src=url;
// for img file(s), read the file & draw to canvas
}else{
handleFiles(e.dataTransfer.files);
}
}
// read & create an image from the image file
function handleFiles(files) {
for (var i=0;i<files.length;i++) {
var file = files[i];
var imageType = /image.*/;
if (!file.type.match(imageType)){continue;}
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
var reader=new FileReader();
reader.onload=(function(aImg){
return function(e) {
aImg.onload=function(){
ctx.drawImage(aImg,0,0);
}
// e.target.result is a dataURL for the image
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
} // end for
} // end handleFiles
}; // end $(function(){});
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<!doctype html>
<html>
<body>
<h4>Drag an image from below onto the canvas, or<br>Drag an image file from your desktop onto the canvas.</h4>
<canvas id="canvas" width=300 height=300></canvas>
<br>
<img width="50" src="https://cfl.dropboxstatic.com/static/images/index/rebrand/logos/glyphs/glyph_french_vanilla.svg">
</body>
</html>
Here is a set of (stripped down) tools I use to play with images
var imageTools = (function () {
var tools = {
canvas : function (width, height) { // create a blank image (canvas)
var c = document.createElement("canvas");
c.width = width;
c.height = height;
return c;
},
createImage : function (width, height) {
var image = this.canvas(width, height);
image.ctx = image.getContext("2d");
return image;
},
loadImage : function (url, callback) {
var image = new Image();
image.src = url;
image.addEventListener('load', cb);
image.addEventListener('error', cb);
return image;
},
image2Canvas : function (img) {
var image = this.canvas(img.width, img.height);
image.ctx = image.getContext("2d");
image.drawImage(ig, 0, 0);
return image;
},
getImageData : function (image) {
return (image.ctx || (this.image2Canvas(image).ctx)).getImageData(0, 0, image.width, image.height).data;
},
};
return tools;
})();
After it is parsed you will have the global variable imageTools
To load and get the image data you will have to wait for the image load callback.
var image;
var imageData;
function loaded(event){
if(event.type === "load"){
image = imageTools.image2Canvas(this);
imageData = imageTools.getImageData(image);
// image data is now in the typed array
// imageData.data
// with imageData.width and imageData.height holding the size
// there are 4 bytes per pixel in the form RGBA
}
}
imageTools.loadImage(imageURL,loaded);
To put the data back into the image after using the imageTools
// image.ctx is non standard and is a result of the imageTools adding the
// attribute ctx
image.ctx.putImageData(imageData,0,0);
To get the URL from the drop event which may be more than one image
var fileList = []; // a list of dropped images
// function called when images dropped
var imagesDropped = function(){
fileList.forEach(function(image){
// image.name is the image URL
// image.type is the mime type
});
fileList = []; // clear the file list
}
var dropEvent = function (event) {
var i,j, imagesFound;
imagesFound = false;
event.preventDefault();
dt = event.dataTransfer;
for (i = 0; i < dt.types.length; i++) { // for each dropped item
if (dt.types[i] === "Files") { // content from the file system
for (var j = 0; j < dt.files.length; j++) {
// check the mime type for the image prefix
if (dt.files[j].type.indexOf("image/") > -1){
fileList.push({ // add to image list
name : dt.files[j].name,
type : dt.files[j].type,
});
imagesFound = true; // flag images found
}
}
}
}
if(imagesFound){ // if images dropped call the handling function
imagesDropped();
}
}
Please note this is an example only and is not a cross browser solution. You will have to implement a variety of drop managers t cover all the browsers. This works on Chrome so covers the majority of users.
I have this code which should get the base64 of the captured image, then save it as a jpg into the devices SD card, under the foler MyAppFolder. However it wont work and i cannot figure out why
<html>
<head>
<script src=../cordova.js></script>
<script>
// A button will call this function
//
function capturePhoto() {
sessionStorage.removeItem('imagepath');
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50, destinationType: Camera.DestinationType.FILE_URI });
}
function onPhotoDataSuccess(imageURI) {
// Uncomment to view the base64 encoded image data
// console.log(imageData);
// Get image handle
//
var imgProfile = document.getElementById('imgProfile');
// Show the captured photo
// The inline CSS rules are used to resize the image
//
imgProfile.src = imageURI;
if(sessionStorage.isprofileimage==1){
getLocation();
}
movePic(imageURI);
}
// Called if something bad happens.
//
function onFail(message) {
alert('Failed because: ' + message);
}
function movePic(file){
window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError);
}
//Callback function when the file system uri has been resolved
function resolveOnSuccess(entry){
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
var myFolderApp = "MyAppFolder";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, successMove, resOnError);
},
resOnError);
},
resOnError);
}
//Callback function when the file has been moved successfully - inserting the complete path
function successMove(entry) {
//Store imagepath in session for future use
// like to store it in database
sessionStorage.setItem('imagepath', entry.fullPath);
}
function resOnError(error) {
alert(error.code);
}
</script>
</head>
<body>
<button onclick="capturePhoto()">Take photo</button>
<img src="" id="imgProfile" style=position:absolute;top:0%;left:0%;width:100%;height:100%;>
</body>
</html>
when the button is pressed, the camera doesnt launch.
I solved it as follow. It might help you:
function capturePhoto() {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoSuccess, function(message) {
alert('Image Capture Failed');
}, {
quality : 40,
destinationType : Camera.DestinationType.FILE_URI
});
}
function onPhotoSuccess(imageURI) {
var gotFileEntry = function(fileEntry) {
alert("Default Image Directory " + fileEntry.fullPath);
var gotFileSystem = function(fileSystem) {
fileSystem.root.getDirectory("MyAppFolder", {
create : true
}, function(dataDir) {
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
// copy the file
fileEntry.moveTo(dataDir, newFileName, null, fsFail);
}, dirFail);
};
// get file system to copy or move image file to
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFileSystem,
onFail);
};
// resolve file system for image
window.resolveLocalFileSystemURI(imageURI, gotFileEntry, fsFail);
// file system fail
var onFail = function(error) {
alert("failed " + error.code);
};
var dirFail = function(error) {
alert("Directory" + error.code);
};
The button wont get clicked because your image src is overlapping it.
Change the position of image src and your code shall work fine