Jcrop: How to overcome low resolution images after cropping? - image

I am currently working on a solution, where I crop an image to a rectangle using jcrop so I can use it as a texture for a 3D cube (in three.js)
AND I can save the cropped area as an image on the server.
The Problem here is, that the cropped image looks not good, it has low quality.
At first I thought it has something to do with the DPI, because it saves in 96 DPI, but some images that I upload do also have 96 dpi and have good quality.
I think it has something to do with jcrop. Do someone know or had any experience with jcrop regarding this issue? Or should I use a different plugin?
Original Image
Cropped Image

why don't you use php resize image system.
i am using it on my website.
Check demo resize wallpaper (check screen shoot) : Happy diwali wallpaper
and original wallpaper (download button as well as below resize option at the page) diwali wallpaper
you ca use
function resize($newWidth, $targetFile, $originalFile) {
$info = getimagesize($originalFile);
$mime = $info['mime'];
switch ($mime) {
case 'image/jpeg':
$image_create_func = 'imagecreatefromjpeg';
$image_save_func = 'imagejpeg';
$new_image_ext = 'jpg';
break;
case 'image/png':
$image_create_func = 'imagecreatefrompng';
$image_save_func = 'imagepng';
$new_image_ext = 'png';
break;
case 'image/gif':
$image_create_func = 'imagecreatefromgif';
$image_save_func = 'imagegif';
$new_image_ext = 'gif';
break;
default:
throw new Exception('Unknown image type.');
}
$img = $image_create_func($originalFile);
list($width, $height) = getimagesize($originalFile);
$newHeight = ($height / $width) * $newWidth;
$tmp = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if (file_exists($targetFile)) {
unlink($targetFile);
}
$image_save_func($tmp, "$targetFile.$new_image_ext");
}
Source: Resize images with PHP, support PNG, JPG

Related

Imagick::steganoImage() Unable to show the watermark

I'm trying to use Imagick::steganoImage with an example image from wikimedia commons.
If I try to show the decoded image of the watermark, I always obtain the 1 pixel image you can see below, whatever image I choose as source.
Anyone may help me to understand why and how I can sort this out?
<?
header("Content-Type: image/png");
// Create a new imagick object
$image = new Imagick('https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Frostedbubble2.jpg/640px-Frostedbubble2.jpg');
$watermark = new Imagick('LABEL:Hello World!');
// The decoding process must "know" about the watermarks size, and starting
// pixel offset.
define('STEGANO_OFFSET', 64); // Secret offset
define('STEGANO_WIDTH', $watermark->getImageWidth());
define('STEGANO_HEIGHT', $watermark->getImageHeight());
$stegano = $image->steganoImage($watermark, STEGANO_OFFSET);
$stegano->writeImage('output.png');
$decoded = new Imagick();
$decoded->setSizeOffset(STEGANO_WIDTH, STEGANO_HEIGHT, STEGANO_OFFSET);
$decoded->readImage('STEGANO:output.png');
$decoded->writeImage('decoded.png');
// Show the output
$decoded->setImageFormat('png');
echo $decoded->getImageBlob();
?>
I tried also the code at this page https://www.geeksforgeeks.org/php-imagick-steganoimage-function/ and the geeksforgeeks image is shown correctly but the stegano image appear as totally black.
<?php
// Create a new imagick object
$imagick = new Imagick(
'https://media.geeksforgeeks.org/wp-content/uploads/geeksforgeeks-13.png');
// Create another Imagick object containing watermark
$watermark = new Imagick('label:This is my secret.');
// Hide $watermark inside $imagick
$imagick = $imagick->steganoImage($watermark, 64);
// Write image to the local folder
$imagick->writeImage('output.png');
// Set the offset
$imagick->setSizeOffset($watermark->getImageWidth(),
$watermark->getImageHeight(), 64);
// Read the encoded image and extract secret
$imagick->readImage('STEGANO:output.png');
// Show the output
$imagick->setImageFormat('png');
header("Content-Type: image/png");
echo $imagick->getImageBlob();
?>
Looks like new Imagick('LABEL:Hello World!'); is no longer enough for a simple label. You'll need to set the size of the canvas, and the point size BEFORE reading the label.
define('STEGANO_OFFSET', 64); // Secret offset
define('STEGANO_WIDTH', 88);
define('STEGANO_HEIGHT', 14);
$watermark = new Imagick();
$watermark->setSize(STEGANO_WIDTH, STEGANO_HEIGHT);
$watermark->setPointSize(16);
$watermark->readImage('LABEL:Hello World!');
$stegano = $image->steganoImage($watermark, STEGANO_OFFSET);
I can't speak when/why this changed, but if you run the following...
convert 'label:Hello World!' decoded.png
... you would have the same image previously extracted from STEGANO:

what are the major differences between image asset and bitmap factory plugin

I'm trying to resize my image size before uploading it to server. I got to know that one can resize the image by keeping its aspect ratio using image asset. Though the image size was reduced the quality is very poor, and one more option i found is bitmap factory.
So, by using bitmap does the image quality is better than using image asset. kindly clarify this. Since the plugin is giving lot of errors currently. i don't want to waste time solving those if i don't get better quality images.
When it comes to resizing the image, both image-asset module and bitmap factory plugin does the same job.
Apart from resizing, the bitmap factory plugin also allows you to draw objects / write text over image. I'm not sure how it makes you a difference with image quality, but if you check the code it is almost the same for resizing.
I tried with both image resizing, and i don't know why i see some
better quality image from bitmap than image asset
. you can check yourself with this below code.
For Bitmap
let w = imageSourceModule.fromFile(img).width;
let h = imageSourceModule.fromFile(img).height;
var bmp = BitmapFactory.create(w, h);
const asset_1 = new ImageAsset(img);
imageSourceModule.fromAsset(asset_1)
.then(img_1 => {
bmp.dispose(function (b) {
b.insert(BitmapFactory.makeMutable(img_1));
// ## Max dimension. Respects aspect ratio.
var b2 = b.resizeMax(250);
var thumb_image = b2.toImageSource();
console.log("-----thumb_image------");
console.log(thumb_image);
if (thumb_image) {
console.log("bit map File successfully deleted....!");
thumb_image.saveToFile(pathDest_1, "jpg");
}
});
})
For Image Asset
const asset = new ImageAsset(img);
asset.options = {
width: 250,
height: 250,
keepAspectRatio: true,
autoScaleFactor: true,
};
imageSourceModule.fromAsset(asset)
.then(img => {
img.saveToFile(pathDest, "jpg");
})

uploading Image texture creating moire

We have implemented FineUploader and are running into an issue with some images that our clients are uploading. For large image files with a repeated canvas texture, FineUploader resizes the images fine, but a moiré is introduced into the final image. Is there any way to help prevent this from happening?
Here is an example:
http://205.238.27.187/Hagan/site/Artwork-Detail.cfm?ArtistsID=1110&NewID=10709
This is not because of the quality setting.
Most browsers use linear interpolation rather than bicubic when resizing images.
Fine Uploader uses the default browser image resizing algorithm.
The solution I've found is limby-resize. It uses pixel averaging/a much better resizing algo but is more CPU intensive. There is a link to a demo in the readme file. (Fine Uploader uses the "Crappy" method)
In megapix-image.js around line #168 or in the fine uploader source code,
Replace:
else {
ctx.drawImage(img, 0, 0, width, height);
}
canvas.qqImageRendered && canvas.qqImageRendered();
With:
else {
var tmpCanvas = document.createElement("canvas");
tmpCanvas.width = iw;
tmpCanvas.height = ih;
var tmpCtx = tmpCanvas.getContext("2d");
tmpCtx.drawImage(img, 0, 0);
canvasResize(tmpCanvas, canvas, function () {
alert("Image resized by limby-resize");
canvas.qqImageRendered && canvas.qqImageRendered();
});
}
And include limby-resize's canvas_resize.js before the fine uploader js file in your HTML.

Animated gif from base64 datastring and false results

Hello im uploading from input form a data:image, its works well with png and jpg
but i cant get work it with GIF.
<input value="data:image/gif;base64,...................................." type="hidden" />
What i need:
Create a file from a string with out losing animation. (the other problem)
Copy to a folder
The problem
Whatever gif im trying to upload i get a error from if (!$image) that image is not valid. Why ?
If i remove $image = #imagecreatefromgif($image); All works but image copied is only first frame from the gif, so its not animated (i heard GD have problems with it, maybe i can just copy full image from datestring, but how to save it right ? )
Im tried to use Gifencoder and Gifdecoder and imagemagick but the problem its doesn't recognize a image from datastring , i need to blob it ?
Here is my code
function ImageUploadString($data_string)
{
$data_string = str_replace('data:image/gif;base64,', '', $data_string);
$data_string = base64_decode($data_string); // decode image from base64
$image = imagecreatefromstring($data_string);
if ($image !== false) {
$random_imagename = str_shuffle(MD5(microtime()));
$extention = "gif";
$ufname = 'folder/'.$random_imagename.'.'.$extention;
$image = #imagecreatefromgif($image); /* Attempt to open */
if (!$image) {
imagedestroy($image);
die('gif error');
}
imagegif($image, $ufname);
}
}
$imagebase = "data:image/gif;base64,..........................................";
ImageUploadString($imagebase);

Images turning sideways/upside down after being uploaded via PhoneGap (iOS)

Not sure what would be causing this, but when I upload some images to my remote server via FileTransfer(), the images sometimes show up either sideways or upside down. However, when I view the images locally on the iPhone, they are positioned in the correct way.
For example, when I select an image like this to upload: http://sharefa.st/view/WBe2QNSK8r8z
It will turn out like this: http://sharefa.st/view/EWdW1Z4G8r8z
I am using the local path to transfer the file, so I don't understand why the image would rotate "randomly".
Here is my upload function:
function uploadPhoto() {
var options = new FileUploadOptions();
options.fileKey = 'file';
options.fileName = imgURI.substr(imgURI.lastIndexOf('/')+1);
options.mimeType = 'image/jpeg';
var params = new Object();
if(logged_in == true) {
params.unique_id = app_unique_id;
params.secret_key = user_secret_key;
}
options.params = params;
loadingStart();
var ft = new FileTransfer();
ft.upload(imgURI, 'http://' + remote_server + '/API/upload', uploadDetails, fail, options);
}
imgURI value looks like this:
file://localhost/var/mobile/Applications/<snip>/tmp/photo_015.jpg
Any insight is appreciated.
Thanks to Humanoidism pointing out that the issue was in fact with the iPhone, and the way it stored images, I was able to figure out a solutuion.
To upload photos in the correct orientation you must add the correctOrientation setting to the options array in getPicture(), and set it to true.
Here are two examples:
function capturePhoto() {
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 30, correctOrientation: true });
}
function getPhoto(source) {
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 30,
destinationType: destinationType.FILE_URI,
sourceType: source,
correctOrientation: true });
}
The problem is not PhoneGap but iPhone. The iPhone was designed to be used as a wide lens camera. Turn the phone sideways when taking pictures or capturing video if you intend to view them on desktop. Your phone will display them correctly, because it "knows" how you took them, but the computer that you're viewing it on dosen't.
What you could do to prevent this is to rotate the picture before the upload. This is not a recommended fix but at least people on desktop computers will be able to see it. Though when viewing them on iPhone they'll be rotated - maybe a check for mobile devices wether or not to rotate the image could come in handy - but still again, not recommended.

Resources