I am developing a plugin in elgg which has a some images for profile icon.
in that plugin there are various sized file for a single image for eg
train.jpg = Height : 100px || Width : 100px
train_25px.jpg = Height : 25px || Width : 25px
Like above i have cropped images. there are about 25 images + 25 cropped images
i want to define one image per user and call the image at any time without recreating the same image in another location
for eg :
Original Location : sitepath/mod/plugin_name/graphic/profile_icon1/master.jpg
User Image Location : site_temp_path/year/month/user_guid/master.jpg
My php function is
global $CONFIG;
function identicon_init() {
extend_view('profile/editicon', 'identicon/editicon');
register_action('identicon/preference', false, $CONFIG->pluginspath . 'identicon/actions/preference.php');
register_plugin_hook('entity:icon:url', 'user', 'identicon_usericon_hook', 900);
}
function identicon_usericon_hook($hook, $entity_type, $returnvalue, $params) {
if (($hook == 'entity:icon:url') && ($params['entity'] instanceof ElggUser)) {
$ent = $params['entity'];
if ($ent->preferIdenticon || !$returnvalue) {
return identicon_url($ent, $params['size']);
}
} else {
return $returnvalue;
}
}
function identicon_url($ent, $size) {
global $CONFIG;
return $CONFIG->wwwroot . 'mod/fp_auto_profile_image/img.php?entity=' . $ent->getGUID() . '&size=' . $size;
}
register_elgg_event_handler('init','system','identicon_init');
use elgg_get_data_path() instead of $CONFIG->wwwroot
then create icon.php and return path to icon.php in identicon_usericon_hook along with required with and size
then in icon.php have this code
$news_guid = get_input('guid');
$contents = readfile(filepath);
$size = strtolower(get_input('size'));
if (!in_array($size, array('large', 'medium', 'small', 'tiny', 'master', 'topbar')))
$size = "large";
header("Content-type: image/jpeg");
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+10 days")), true);
header("Pragma: public");
header("Cache-Control: public");
header("Content-Length: " . strlen($contents));
header("ETag: \"$etag\"");
echo $contents;
Related
I'm trying to show a video on my Mac and I phone but I can't get it to work. My videos are served by php, I've been reading it has to do with range headers not being sent but I can't figure out how to do it correctly.
Heres what I have so far:
HTML:
<video controls="true" autoplay muted loop>
<source src="http://my_site.com/video/394934" type="video/mp4">
</video>
PHP:
// Get file GUID
$file_guid = (int) get_input('file_guid', 0);
// Get file thumbnail size
$size = get_input('size', 'small');
$file = get_entity($file_guid);
if (!elgg_instanceof($file, 'object', 'file')) {
exit;
}
$simpletype = $file->simpletype;
if ($simpletype == "image") {
// Get file thumbnail
switch ($size) {
case "small":
$thumbfile = $file->thumbnail;
break;
case "medium":
$thumbfile = $file->smallthumb;
break;
case "large":
default:
$thumbfile = $file->largethumb;
break;
}
// Grab the file
if ($thumbfile && !empty($thumbfile)) {
$readfile = new ElggFile();
$readfile->owner_guid = $file->owner_guid;
$readfile->setFilename($thumbfile);
$mime = $file->getMimeType();
$contents = $readfile->grabFile();
// caching images for 10 days
header("Content-type: $mime");
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+10 days")), true);
header("Pragma: public", true);
header("Cache-Control: public", true);
header("Content-Length: " . strlen($contents));
echo $contents;
exit;
}
}
if it is in fact a range headers issue, there's a github project with a code example tackling this issue for Safari/Mac:
https://gist.github.com/codler/3906826
I have a server set up to serve web pages on different domains (specifically a mobile device or localhost:9000 where laravel is serving on localhost:8000). I'm trying to return image requests on these pages to my laravel server but I'm running into problems. From a forum post, I thought that setting headers on a request would do the trick but, when I navigate to /api/v1/images/default.jpg, no default cat image is shown. Instead, I get a box with no image.
Now, the image is in my public folder so if I browse to /public/images/default.jpg I do see my cat image, but I'd rather serve images within my /api/v1/... route.
Route::get('images/{imageName}', function($imageName){
$img = 'public/images/' . $imageName;
// return $img;
echo $img . "\n\n";
if(File::exists($img)) {
// return "true";
// return Response::make($img, 200, array('content-type' => 'image/jpg'));
// return Response::download($img, $imageName);
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: inline; filename=\"".$imageName."\"");
header("Content-Type: image/jpg");
header("Content-Transfer-Encoding: binary");
//stream the file out
readfile($img);
exit;
} else {
return "false";
}
return $img;
// return File::exists($img);
// return File::isFile('/images/' . $imageName);
// return $imageName;
// if(File::isFile('images/' + $imageName)){
// return Response::make('images/' + $imageName, 200, array('content-type' => 'image/jpg'));
// }
});
Use the Response::stream method to do it:
Route::get('/image', function () {
return Response::stream(function () {
$filename = '/path/to/your/image.jpg';
readfile($filename);
}, 200, ['content-type' => 'image/jpeg']);
});
In case you want to stream your image from a ftp server ($imageName is the parameter)
$server = \Config::get('ftpconfig.server');
$usuario = \Config::get('ftpconfig.user');
$password = \Config::get('ftpconfig.password');
$path = \Config::get('ftpconfig.path');
$file_location = "ftp://$usuario:".urlencode($password)."#".$server.$path.$imageName;
$headers = [
"Content-Type" => "image/jpeg",
"Content-Length" => filesize($file_location),
"Content-disposition" => "inline; filename=\"" . basename($file_location) . "\"",
];
return \Response::stream(function () use ($file_location){
readfile($file_location);
}, 200, $headers)
#Andrew Allbright,
If your images are located inside the laravel app directory then you can use
$img = app_path().'/api/v1/images/' . $imageName;
For image manipulation you can try Intervention
class function (located php/php_includes/easyCMSv2.php)
public function get_file($file){
ob_start();
include('php/'.$file);
$file = ob_end_clean();
return $file;
}
stylesheet_config.php (located php/css)
<?php
$blue = "#4C66A4";
$red = "#A44C4C";
?>
stylesheet.php (located php/css)
<?php
ob_start ("ob_gzhandler");
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$if_modified_since = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
} else {
$if_modified_since = '';
}
$mtime = filemtime($_SERVER['SCRIPT_FILENAME']);
$gmdate_mod = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
if ($if_modified_since == $gmdate_mod) {
header("HTTP/1.0 304 Not Modified");
exit;
}
header("Last-Modified: $gmdate_mod");
header('Content-type: text/css');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
include_once('../php_includes/easyCMSv2.php');
require('stylesheet_config.php');
$cms = new Template($connect);
if(isset($_GET['v'])){
$cms->get_file('css/'.$_GET["v"].'.php');
}
?>
$_GET['v'] = 1-23-1
1-23-1.php (located php/css)
div{
color:<?=$blue?>;
background:<?=$red?>;
}
Though everytime I go to the url (either by a link tag or direct url) it returns 1 can anyone explain to me why it keeps returning 1?
ob_end_clean() returns true or false (in your case, true, or 1). It does not return the actual buffer output.
You need to use another method to retrieve the buffer output: ob_get_contents()
public function get_file($file){
ob_start();
include('php/'.$file);
$file = ob_get_contents(); /* *** */
ob_end_clean();
return $file;
}
I have this short external php script (named resize.php) which I am calling to from other php scripts when I want to resize/thumbnail images.
I would like to change the script to work as an internal function instead of an external php script and I don't know how to convert it to a function that will do the job.
This is how it is being called:
<img src="resize.php?image=images/IMG228.jpg&width=165" border="0" alt="foo" width="165" height="165" title="">
The main reason I want to change it to be a function is because due to caching issues, when it is an external php script, if it has already been called/loaded by the browser, it doesn't load it again, even if the image on the server (to be resized) is newer, and despite the fact that the resizer.php itself had a caching detection and refresh implemented. If it is an internal resizer function, I assume this issue will be resolved.
This is the resizer.php script:
<?php
if (isset($_GET['image']) && isset($_GET['width']) && is_numeric($_GET['width'])) {
// Get image name
$original_image = $_GET['image'];
// Watermarks
$wmark = 'watermark.png'; //largest watermark
$wmarkm = 'watermark_m.png'; //medium watermark
$wmarks = 'watermark_s.png'; //smallest watermark
$wmarkno = 'nowatermark.png'; //No watermark
// Maximum image width
$max_width = (int) $_GET['width'];
// Maximum image height
$max_height = "800";
if (file_exists($original_image)) {
$cached = 'cache/' . preg_replace('/(\.\w+$)/', ".{$max_width}\\1", $original_image);
if (file_exists($cached)) {
$cst = stat($cached);
$fst = stat($original_image);
if ($fst[9] <= $cst[9] && $fst[10] <= $cst[10]) {
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $cst[9]) {
// header("HTTP/1.0 304 Not Modified");
header("HTTP/1.1 304 Not Modified");
// header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($cached)).' GMT', true, 304);
} else {
header('Content-type: image/jpeg');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $cst[9]) . ' GMT');
header('Cache-Control: private');
// print file_get_contents($cached);
readfile("{$cached}");
}
exit;
}
}
if ($max_width > 300) {
$watermark = $wmark;
} elseif ($max_width > 152 && $max_width < 300) {
$watermark = $wmarkm;
} elseif ($max_width > 50 && $max_width < 151) {
$watermark = $wmarks;
} else {
$watermark = $wmarkno;
}
//create the resized image
exec("gm convert -filter Lanczos {$original_image} -thumbnail {$max_width}x{$max_height} -quality 90 -unsharp 2x0.5+0.7+0 {$cached}");
//apply the watermark and recreate the watermarked image, overwriting the previously resized image
exec("gm composite -quality 90 -dissolve 100 -gravity center {$watermark} {$cached} {$cached}");
header('Content-type: image/jpeg');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: private');
readfile("{$cached}");
}
}
?>
Like this?
img_resize.php
<?php
function resizeImage($image, $width)
{
if(file_exists('c:/server/path/to/images/folder.'.$image) && ctype_digit($width) && $width >= 1)
{
// awesome image resizing code
}
}
?>
some frontend script which the user uploads their picture to: resize.php ?
<?php
include_once('c:/path/to/img_resize.php');
resizeImage('user12345_profilepic.jpg', 165);
?>
I have been looking for a solution to a problem I'm having with my code. The nearest solution to my problem was found here however that solution didn't fit my problem.
I'm listing uploaded files in PHP on my page, with each file being an to the file's location. That works fine, however I am new to PHP and am having difficulty in implementing others code.
Here's the code I'm using, if it helps:
<?php
// Directory Location
$directory = './';
// Timezone (UK BST)
date_default_timezone_set(WET);
// Define Byte Sizes
function file_size($size)
{
$filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
return $size ? round($size/pow(1024, ($i = floor(log($size, 1024)))), 1) . $filesizename[$i] : '0 Bytes';
}
// fetches all executable files in that directory and loop over each
foreach(glob($file.'*wav') as $file) {
// List Link to Files & Date/Time
echo '<a class="files" href="'.$file.'">
<span class="time">' . date("m/d/Y H:i", filemtime($file));
// List File Name & Size
echo '</span> '.$file.'
Size: '.file_size(filesize($file)).'</a>';
}
?>
If possible I would prefer the download links to be generated in PHP for each individual file. The files are listed like this: http://i.stack.imgur.com/N8Lxa.png
You should use the code of the mentioned SO answer in the following way:
change the link you display to the following which direct the user to download.php and hands over the information which file to download:
echo '<a class="files" href="download.php?file='.$file.'"> ...
Then add an download.php with the content of the SO answer but using
$filename = $_GET['file'];
to get the given filename out of the url.
Additionally you have to change header('Content-Type: application/pdf'); to whatever filetype you want to be downloaded.
for list of files list.php e.g.
<?php
// salt for md5 check
$saltmd5 = '76t7gjbertdfv56w45sdve54etyv';
// Directory Location
$directory = './';
// Timezone (UK BST)
date_default_timezone_set(WET);
// Define Byte Sizes
function file_size($size)
{
$filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
return $size ? round($size/pow(1024, ($i = floor(log($size, 1024)))), 1) . $filesizename[$i] : '0 Bytes';
}
// fetches all executable files in that directory and loop over each
foreach(glob($file.'*wav') as $file) {
// List Link to Files & Date/Time
$file_md5 = md5("$file$saltmd5"); // md5 file check
$file_link = "dwn.php?f=$file&c=$file_md5"; // file link
echo '<a class="files" href="'.$file_link.'">
<span class="time">' . date("m/d/Y H:i", filemtime($file));
// List File Name & Size
echo '</span> '.$file.'
Size: '.file_size(filesize($file)).'</a>';
}
?>
for download of files dwn.php e.g.
<?php
// salt for md5 check
$saltmd5 = '76t7gjbertdfv56w45sdve54etyv';
$file_md5 = $_GET['c']; // md5 file check
$filename = $_GET['f']; // the name of the file that is downloaded
if($file_md5==md5("$filename$saltmd5")){
// Directory Location
$directory = './';
$size = filesize($directory . $filename) ;
header("Content-Type: application/force-download; name=\"". $filename ."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ". $size ."");
header("Content-Disposition: attachment; filename=\"". $filename ."\"");
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo (readfile($directory . $filename));
}
else
{
die('no existo'); //bad file
}
?>