Profile picture upload with picture cropping PHP - php

Background
Hi there, I have been recently working on a project of mine which allows users to login and signup to the system. This has been done in PHP. Once the user logs in to the system I have allowed them to upload a profile picture. The upload works and the profile picture displays.
What I would like to happen
I want to allow the user to crop the image they have uploaded to a 150x150 image so that it fits nicely when shown on the page.
What have I already tried
I have uploaded the image as normal and used GD from PHP to crop the image. When this happened, the image didn't crop to where I think the user would have wanted to crop it. The subject of the image was on the right like this example: https://i.pinimg.com/originals/29/a1/9b/29a19bb78244f8a7229fa13c21dbcd50.jpg
In this example I think the user would have chosen the tree as the subject. (I know I can select a crop area but I will not know where the subject of the image is hence my question)
What I have achieved so far
Here is an image of what I have created so far:
The slightly opaque overlay over the image is what I want the cropped area to be. This area is draggable using js. I have managed to choose the direction of the image using JS.
Here is the function that moves the overlay when a user clicks and drags it:
function elementDrag(e)
{
e = e || window.event;
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
// decides which direction is allowed for dragging
if(width > height)
{
//landscape
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
//elmnt.style.left = (l+p_dims.left) + "px";
}
else
{
//portrait or sqaure
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
//elmnt.style.top = (elmnt.offsetTop - (t+p_dims.top)) + "px";
}
}
This is the area where I would potentially like to change it so that overlay doesn't go past the image dimensions on screen
What I have failed to do
I wanted to make the draggable overlay only over the area of the image and not the whole page. Once the overlay has been placed the user should be allowed to click the crop button to crop the image. I know how to crop the image using a crop area in PHP and upload it afterwards.
I did find this js library but not keen on using it, I will though if it is a last resort. https://github.com/Foliotek/Croppie
So how do I do this without using any PHP libraries if possible? Thanks in advance.

I've been dealing with something like this. Croppie seamed like a very viable option. I tried it out and it works wonders. Have been using it every since. Great little tool. Highly recommend you use it.

Related

Merge signature image onto a pdf loaded in a div

For a project I need to load a pdf file onto a div. On clicking a button a canvas will be opened where the user will draw his signature and then on clicking the add button present in the canvas, the user should be able to place the canvas signature as an image on to the pdf. At last on clicking the final button the image should get merged onto the pdf.
I did the above task in the following way:
Converted pdf into series of images using GhostScript.
Loaded the converted images onto a div.
On clicking the button a canvas will be opened and the user will sign in it and on clicking the add button present in the canvas, the user will be able to place the image onto the image of pages loaded in the div.
I obtain the page Id which is the page number and the signature image placed coordinate using e.clientX and e.clientY.
Then I pass all those 3 values to a php script which uses fpdf and fpdi to merge the image onto the pdf.
I'm not able to place the image properly because e.clientX and e.clientY makes use of pixel as units where as fpdf uses mm as units. I'm trying to sort out that.
Is there any other way to do this in a simpler way. i.e., directly loading the pdf onto the div and merging the signature instead of what I've explained above.
You may try Firefox's PDF.js, which you can make use of, in your project. A sample code would be:
PDFJS.getDocument('helloworld.pdf').then(function(pdf) {
// Using promise to fetch the page
pdf.getPage(1).then(function(page) {
var scale = 1.5;
var viewport = page.getViewport(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
};
page.render(renderContext);
});
});
There are Javascript-Libraries like Mozillas pdf.js that render PDF-Files directly in the browser into a canvas. That might be a possibility to circumvent the image-rendering process. But as far as I know those libraries have problems with CMYK-PDFs. Therefore the safe way would be to do the image rendering.
As for embedding the signature into the pdf I can't see any other way then the one described by you. The aforementioned libraries all are only displaying the PDF-file so they can not write into the PDF.
Hope that helps
You can look at Applidok PDF service, which allow to have signature area, so that form user will have the chance to either upload signature image, or to draw it on a canvas, so that it get merged on his custom PDF document generated at end.
An example is online at http://pipnee.com/P398D433C .

How to preload a set of images and then start the image slideshow?

I'm creating a slideshow with 5 frames (each of which will have its own slideshow of images) with huge images and it takes some time for the first few images in each frame to be loaded(the rest of the images are loaded really fast). So I was thinking I could preload a simple black images (the background is black) and then start my slideshow once I know the images have loaded. Also, the slideshow images are dynamic, ie their urls change every day.
Does anyone know how I could do that? Because what I've found online only preloads an image but says nothing about how to start my slideshow after that.
Or if anyone has a better solution, please let me know!
FYI, for the slideshow I've used PHP to extract the image urls into a file and JavaScript to read them from it and display them in the slideshow.
Thanks!
A good way to preload images is to load them outside of the frame using css with position: absolute, i can remember reading that using display: none; it would not get downloaded by Safari.
This seems to be an elegant way to precache the images.
"Per Paul Irish, the canonical plugin for detecting image load complete events is now at:
https://github.com/desandro/imagesloaded"
Source: jQuery event for images loaded
This should work
/*You could populate this array through an xml to something if there are too many images*/
var arrUrls = ["image1.jpg", "image2.jpg", "image3.jpg"];
var nLoadCount = 0;
for(var i=0;i<arrUrls.length;i++)
{
var oImage = new Image ();
oImage.onload = function ()
{
nLoadCount++;
if(nLoadCount == arrUrls.length)
{
/*Show your content here*/
}
}
oImage.src = arrUrls[i];
}

Viable solution for cropping an image in a 'lightbox' that has dimensions larger than most desktop resolutions

I am using Lightview 3 to display an image within an iframe. This has a form that allows the user to zoom in and out of the image and submit the form to generate a thumbnail based on the image in view when the form has been submitted.
The issue I have is that we have to use massive images (width 1100px+) etc.. so having this open in a lightview doesn't really look great as you have scrolling bars within the iframe.
What is the best way to have the image displayed at half of its size and using some form of scaling when it does create the thumbnail of the fullsize image correctly. Can anyone suggest some methods to do this?
I have done this type of thing many times. My environment is ASP.NET using Visual Basic and the technologies I used to achieve my desired result where FancyBox, JCrop, and Uploadify.
First I set up FancyBox (haven't used FancyBox2 yet) to open a modal popup window with a iframe with a page that has a preview area (344x270 in my case) and a place to upload an image using uploadify.
Once an image is uploaded, validated, and thumbnail created I create an object that holds information about this image. This includes file name, extension, original width and height, and a new width and height to scale the image to fit my 344x270 preview (cropbox) area.
To find this new width and height I use the following code written in VB.NET:
Dim objImage As System.Drawing.Image = System.Drawing.Image.FromFile(path)
Dim orig_h = objImage.Height
Dim orig_w = objImage.Width
Dim cropbox_width, cropbox_height As Integer
If objImage.Width > objImage.Height Then
cropbox_width = 344
cropbox_height = (344 / objImage.Width) * objImage.Height
If cropbox_height > 270 Then
Do Until cropbox_height <= 270
cropbox_width = cropbox_width - 1
cropbox_height = (cropbox_width / objImage.Width) * objImage.Height
Loop
End If
Else
cropbox_height = 270
cropbox_width = (270 / objImage.Height) * objImage.Width
If cropbox_width > 344 Then
Do Until cropbox_width <= 344
cropbox_height = cropbox_height - 1
cropbox_width = (cropbox_height / objImage.Height) * objImage.Width
Loop
End If
End If
Basically, I'm trying to determine if its portrait or landscape then find the aspect ratio to scale it down to fit my preview (cropbox) area.
Once this is determined I add them to my object, serialize it and send it back to the upload page (FancyBox iframe), set the image path of the preview (cropbox) area, set it's height and width from the returned object, store the original height and width, and then initiate JCrop.
From here they can crop the image for which I have code to crop the original based on how they have cropped the preview image. I won't go over this code and technique because you didn't ask about cropping.
I know this isn't exactly what you asked for since it sounds like there will be no uploading or cropping going on, but I thought my code for scaling the image down might point you in the right direction.
Fancybox - my favourite (supports many things, not just images)
http://www.designyourway.net/blog/resources/30-efficient-jquery-lightbox-plugins/ This is a fine compiled list of alternatives

Watermark an image upon download...is it possible?

Simple question with yes/no answer and if yes...then how?
Suppose you have an HTML page with an image on it without any sort of watermark.
Is it possible to place a watermark on that image if a user saves it to their computer?
I need a simple function that watermarks an image upon download or save...
I do understand that once the image loads in the browser, it is technically downloaded, so is there a way to display the image without a watermark on screen, and if the user opens browser cache, he/she finds a watermarked copy?
If anybody has done this using any platform (PHP, GD, jQuery, etc.), your contribution would be appreciated.
One trick might be to combine 2 images, so they become one.
I have image A:
Then I add image B (watermark version)
So when you display the image for the user you use one as background and the other one as image, so when user tries to download, they will get only one part. Of course as already mentioned, the user will be able to get all they can see on the screen, but most users won't be able to combine the images properly.
Please note that the image on top must be transparent.
I would recommend doing this server side and cache the modified images when you have cut out the watermark
Here you can read how to do it with PHP: http://www.sitepoint.com/watermark-images-php/
I personally don't think that it is possible with javascript, because as you already have said yourself, it is already downloaded.
But don't nail me on that.
On the server side it is for sure possible, as you can see in the above link.
A possible alternate solution is to contain the image inside an element with a hidden overflow.
For example:
Your image has a height of 200px, you add an extra 20px watermark (when uploading) at the bottom of the image (so it isn't actually on top of the image). So the total image now has a height of 220px; but you place it inside an element give that element a 200px height and a hidden overflow.
You can change the source of the image when a user right-clicks it. This way you can change the source to the watermarked version when the user tries to save the image.
Yes, the user will already have the non-watermarked version in their cache, but only advanced users are going to know how to get to those images.
$('img').on('mousedown', function (event) {
//check which mouse button was clicked, 1 == left, 2 == middle, 3 == right
if (event.which == 3) {
//update the source of this image
this.src = this.src.replace('.jpg', '_watermarked.jpg');
}
});​
Here is a demo: http://jsfiddle.net/s6A9m/
Anything that the user can see they can take. There is no way to watermark ONLY if downloaded. When an image is displayed in the browser it has already downloaded.
There are several approaches you could take. I would recommend you use PHP to add the watermark to the image before it is displayed. This means that all protected images on the site will display a visible watermark. A second approach I have seen used is to display a low quality version that is not watermarked, but restrict the full quality version to only those who are supposed to see it.
Yes it is possible. All you have to do is,
Call the download function, in which we can implement the downloading of watermarked images.
I have used AngularJS, HTML, JQuery and watermarkJS which you find here(http://brianium.github.io/watermarkjs/)
HTML:
Download Sample
Javascript:
$scope.selectedWatermarkType = 'Text';
$scope.selectedPosition = 'Bottom-left';
$scope.text = 'Sample Watermark';
$scope.size = '45';
$scope.selectedFont = 'Arial';
$scope.ColorCodeGlobalObj.colorcode = 'ffff';
$scope.DownloadSample = function () {
if ($scope.selectedWatermarkType == 'Text') {
if ($scope.selectedPosition == 'Bottom-left') {
watermark(['/assets/js/node_modules/watermarkjs/examples/img/shepherd.jpg'])
.image(watermark.text.lowerRight($scope.text, $scope.size + 'px ' + $scope.selectedFont, '#' + $scope.ColorCodeGlobalObj.colorcode, 0.5))
.then(function (img) {
saveImageAs(img);
});
}
}
'img' is the watermarked image object which can be used to download the image.
function saveImageAs(imgOrURL) {
imgOrURL.src.replace('image/png', 'image/octet-stream');
if (typeof imgOrURL == 'object')
imgOrURL = imgOrURL.src;
var link = document.createElement("a");
link.setAttribute("href", imgOrURL);
link.setAttribute("download", 'watermarkSample.png');
link.click();
}
This code performs download of watermarked image. Still the unwatermarked image is available in the mentioned srcpath which can be appended to an 'img' tag and can be viewed.
Hope this helps !

Dynamic images resizing

I'm working on project where we are trying to adopt and resize template images to the various resolutions. For example if the website is viewed in 800px width (800x600) and 1024px width or larger the image size should be viewed in same quality.
I've had in mind to use sprite with 3 types of images for each range of this template , but I'm looking for other ideas , php gd maybe ? Any python solution ?
Well, for resizing it would of course be better to use GD... But indexed, I think. So that you have an upload script that automatically generates the images' in other sizes, and saves them somewhere.
However, it matters whether you have more disk space, or performance... Performance would get worse IF you have many people viewing these images. Disk space would get worse IF you have A LOT of these images.
Python Imaging Library will give you dynamic resizing, processing, etc.
If you are resizing to a known set of resolutions, you can just resize your images once and store them.
If you need to resize for any possible resolution, you will need a library to do that for you. In PHP, GD or ImageMagik are both good.
If you do this, you may want to add caching for the most common resolutions. This will take up more disc space, but will save you the cost of recalculating all the images every time.
Note that it can be difficult to detect the true resolution though. If the browser window is resized, the resolution you think the screen is may not be the actual resolution the user can see. The same can happen if they have toolbars or sidebars opened.
Why not resize the image on the client using JavaScript?
<head>
<script>
function resize() {
ww = window.innerWidth
wh = window.innerHeight
photo = document.getElementById("photo")
// You probably wouldn't actually make the image fill the window, you'd pick
// some appropriate size.
photo.setAttribute("width", ww)
photo.setAttribute("height", wh)
}
</head>
<body onload="resize()" onresize="resize()">
<img id="photo" src="photo.jpg">
Getting the inner window width is quite hard, as different browsers use different variables. However, this is what I use on my website. It gets the inner window width rather reliably, and then sets the image width/height. It shouldn't be too hard to modify this code to set the src of the image desired.
function set_image_sizes(){
if (window.innerHeight != undefined) {
height = window.innerHeight;
width = window.innerWidth;
} else if (document.documentElement.clientHeight > 0) {
height = document.documentElement.clientHeight;
width = document.documentElement.clientWidth;
} else {
height = document.body.clientHeight;
width = document.body.clientWidth;
}
$('#image').css('height', height);
$('#image').css('width', width);
}

Categories