[RESOLU] resize-class.php et responsive design

Eléphanteau du PHP | 26 Messages

25 mars 2014, 11:43

Bonjour, je réalise un site perso et j'ai remarqué que le site ramait sérieusement sur mon iphone.
J'envisage donc d'afficher les images de mes galeries selon le type de périphérique utilisé (ordinateur, tablette ou smartphone)
j'ai cherché des solutions pendant longtemps, j'ai trouvé celle-ci

http://www.jamesfairhurst.co.uk/SkeletonResizeImages/
<!doctype html>
<!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
<!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
<!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> 	<html lang="en"> <!--<![endif]-->
<head>
	<!-- Basic Page Needs
  ================================================== -->
	<meta charset="utf-8" />
	<title>Responsive Images</title>
	<meta name="description" content="">
	<meta name="author" content="">
	<!--[if lt IE 9]>
		<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->
	
	<!-- Mobile Specific Metas
  ================================================== -->
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />

	<!-- CSS
  ================================================== -->
	<link rel="stylesheet" href="stylesheets/base.css">
	<link rel="stylesheet" href="stylesheets/skeleton.css">
	<link rel="stylesheet" href="stylesheets/layout.css">
	
	<!-- Favicons
	================================================== -->
	<link rel="shortcut icon" href="images/favicon.ico">
	<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
	<link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png" />
	<link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png" />
	
</head>
<body>
	<!-- Primary Page Layout
	================================================== -->
	
	<!-- Delete everything in this .container and get started on your own site! -->

	<div class="container">	
		<div class="sixteen columns">
			<h1 class="remove-bottom" style="margin-top: 40px">Responsive Images</h1>
			<p>Resize your browser, go ahead I dare you, I double dare you muther f#@#er</p>
			<hr />
		</div>
		
		<div class="sixteen columns">
			<h2 class="">Responsive Images</h2>
			<div id="images">
				<img src="images/ajax-loader.gif" class="resize js_show loading_image" rel="images/Boston_City_Flow.jpg" />
				<noscript><img src="images/Boston_City_Flow.jpg" /></noscript>
				
				<img src="images/ajax-loader.gif" class="resize js_show loading_image" rel="images/Costa_Rican_Frog.jpg" />
				<noscript><img src="images/Costa_Rican_Frog.jpg" /></noscript>
				
				<img src="images/ajax-loader.gif" class="resize js_show loading_image" rel="images/Pensive_Parakeet.jpg" />
				<noscript><img src="images/Pensive_Parakeet.jpg" /></noscript>
			</div>
		</div>
		
		<div class="one-third column">
			<h3>About?</h3>	
			<p>
				Uses a jQuery & PHP combo to resize images on the fly to certain set widths. 
				Can be made to resize images when a user changes their browser width (like this demo)
				or set to only resize once on the inital browser width (The former has more overhead as
				the script keeps checking and resizing).
			</p>
		</div>
		
		<div class="one-third column">
			<h3>Docs & Support</h3>
			<p>
				Any issues or questions post a comment on the original 
				<a href="http://www.jamesfairhurst.co.uk/posts/view/responsive_images_with_php_and_jquery">blog post</a>.
				This demo is using the <a href="http://www.getskeleton.com">Skeleton</a> boilerplate project.
			</p>
		</div>

	</div><!-- container -->

	<!-- JS
	================================================== -->
	<script src="javascripts/jquery-1.11.0.min.js"></script>
	<script src="javascripts/jquery-common.js"></script>
	<script src="javascripts/app.js"></script>
	
<!-- End Document
================================================== -->
</body>
</html>
<?php

   # ========================================================================#
   #
   #  Author:    Jarrod Oberto
   #  Version:	 1.0
   #  Date:      17-Jan-10
   #  Purpose:   Resizes and saves image
   #  Requires : Requires PHP5, GD library.
   #  Usage Example:
   #                     include("classes/resize_class.php");
   #                     $resizeObj = new resize('images/cars/large/input.jpg');
   #                     $resizeObj -> resizeImage(150, 100, 0);
   #                     $resizeObj -> saveImage('images/cars/large/output.jpg', 100);
   #
   #
   # ========================================================================#


		Class resize
		{
			// *** Class variables
			private $image;
		    private $width;
		    private $height;
			private $imageResized;

			function __construct($fileName)
			{
				// *** Open up the file
				$this->image = $this->openImage($fileName);

			    // *** Get width and height
			    $this->width  = imagesx($this->image);
			    $this->height = imagesy($this->image);
			}

			## --------------------------------------------------------

			private function openImage($file)
			{
				// *** Get extension
				$extension = strtolower(strrchr($file, '.'));

				switch($extension)
				{
					case '.jpg':
					case '.jpeg':
						$img = @imagecreatefromjpeg($file);
						break;
					case '.gif':
						$img = @imagecreatefromgif($file);
						break;
					case '.png':
						$img = @imagecreatefrompng($file);
						break;
					default:
						$img = false;
						break;
				}
				return $img;
			}

			## --------------------------------------------------------

			public function resizeImage($newWidth, $newHeight, $option="auto")
			{
				// *** Get optimal width and height - based on $option
				$optionArray = $this->getDimensions($newWidth, $newHeight, $option);

				$optimalWidth  = $optionArray['optimalWidth'];
				$optimalHeight = $optionArray['optimalHeight'];


				// *** Resample - create image canvas of x, y size
				$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
				imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);


				// *** if option is 'crop', then crop too
				if ($option == 'crop') {
					$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
				}
			}

			## --------------------------------------------------------
			
			private function getDimensions($newWidth, $newHeight, $option)
			{

			   switch ($option)
				{
					case 'exact':
						$optimalWidth = $newWidth;
						$optimalHeight= $newHeight;
						break;
					case 'portrait':
						$optimalWidth = $this->getSizeByFixedHeight($newHeight);
						$optimalHeight= $newHeight;
						break;
					case 'landscape':
						$optimalWidth = $newWidth;
						$optimalHeight= $this->getSizeByFixedWidth($newWidth);
						break;
					case 'auto':
						$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
						$optimalWidth = $optionArray['optimalWidth'];
						$optimalHeight = $optionArray['optimalHeight'];
						break;
					case 'crop':
						$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
						$optimalWidth = $optionArray['optimalWidth'];
						$optimalHeight = $optionArray['optimalHeight'];
						break;
				}
				return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
			}

			## --------------------------------------------------------

			private function getSizeByFixedHeight($newHeight)
			{
				$ratio = $this->width / $this->height;
				$newWidth = $newHeight * $ratio;
				return $newWidth;
			}

			private function getSizeByFixedWidth($newWidth)
			{
				$ratio = $this->height / $this->width;
				$newHeight = $newWidth * $ratio;
				return $newHeight;
			}

			private function getSizeByAuto($newWidth, $newHeight)
			{
				if ($this->height < $this->width)
				// *** Image to be resized is wider (landscape)
				{
					$optimalWidth = $newWidth;
					$optimalHeight= $this->getSizeByFixedWidth($newWidth);
				}
				elseif ($this->height > $this->width)
				// *** Image to be resized is taller (portrait)
				{
					$optimalWidth = $this->getSizeByFixedHeight($newHeight);
					$optimalHeight= $newHeight;
				}
				else
				// *** Image to be resizerd is a square
				{
					if ($newHeight < $newWidth) {
						$optimalWidth = $newWidth;
						$optimalHeight= $this->getSizeByFixedWidth($newWidth);
					} else if ($newHeight > $newWidth) {
						$optimalWidth = $this->getSizeByFixedHeight($newHeight);
						$optimalHeight= $newHeight;
					} else {
						// *** Sqaure being resized to a square
						$optimalWidth = $newWidth;
						$optimalHeight= $newHeight;
					}
				}

				return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
			}

			## --------------------------------------------------------

			private function getOptimalCrop($newWidth, $newHeight)
			{

				$heightRatio = $this->height / $newHeight;
				$widthRatio  = $this->width /  $newWidth;

				if ($heightRatio < $widthRatio) {
					$optimalRatio = $heightRatio;
				} else {
					$optimalRatio = $widthRatio;
				}

				$optimalHeight = $this->height / $optimalRatio;
				$optimalWidth  = $this->width  / $optimalRatio;

				return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
			}

			## --------------------------------------------------------

			private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
			{
				// *** Find center - this will be used for the crop
				$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
				$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );

				$crop = $this->imageResized;
				//imagedestroy($this->imageResized);

				// *** Now crop from center to exact requested size
				$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
				imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
			}

			## --------------------------------------------------------

			public function saveImage($savePath, $imageQuality="100")
			{
				// *** Get extension
        		$extension = strrchr($savePath, '.');
       			$extension = strtolower($extension);

				switch($extension)
				{
					case '.jpg':
					case '.jpeg':
						if (imagetypes() & IMG_JPG) {
							imagejpeg($this->imageResized, $savePath, $imageQuality);
						}
						break;

					case '.gif':
						if (imagetypes() & IMG_GIF) {
							imagegif($this->imageResized, $savePath);
						}
						break;

					case '.png':
						// *** Scale quality from 0-100 to 0-9
						$scaleQuality = round(($imageQuality/100) * 9);

						// *** Invert quality setting as 0 is best, not 9
						$invertScaleQuality = 9 - $scaleQuality;

						if (imagetypes() & IMG_PNG) {
							 imagepng($this->imageResized, $savePath, $invertScaleQuality);
						}
						break;

					// ... etc

					default:
						// *** No extension - No save.
						break;
				}

				imagedestroy($this->imageResized);
			}


			## --------------------------------------------------------

		}
?>
<?php
// *** Include the class
include('resize-class.php');

// list of available image sizes
// insert more sizes for finer grain control but probably not needed
$image_sizes = array(
	'320', // smallest
	'480',
	'768',
	'940' // largest
);

// get base path
$base_path = str_replace(basename(__FILE__),"",__FILE__);

// get window width
$browser_width = (int) $_POST['width'];

// build image path
$image = $base_path.str_replace("/",DIRECTORY_SEPARATOR,$_POST['image']);

// get original image size
$size = getimagesize($image);

// set original width & height
$width = $size[0];
$height = $size[1];

// get the optimum width
foreach($image_sizes as $k=>$v) {
	if((int) $v < $browser_width) {
		$width = (int)$v;
	}
}

// check we're not over re-sizing
if($width > $size[0]) {
	$width = $size[0];
}

// check if the original image can fit on screen
if($size[0] < $browser_width) {
	$width = $size[0];
}

// check against largest image size
$reverse = array_reverse($image_sizes);
if($size[0] > $reverse[0] && $browser_width > $reverse[0]) {
	$width = $reverse[0];
}

// build new filename
$new_image_name = 'cache/'.$width.'_'.basename($image);

// re-sized image already exists
if(file_exists($base_path.str_replace("/",DIRECTORY_SEPARATOR,$new_image_name))) {
	echo $new_image_name;
	exit;
}

// *** 1) Initialise / load image
$resizeObj = new resize($image);
// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
$resizeObj->resizeImage($width, $height);
// *** 3) Save image
$resizeObj->saveImage($new_image_name, 80);

echo $new_image_name;
tout semble bien fonctionner en local, le code génère des images de largeurs variées (320px, 480px, 768px etc) et les stocke dans un dossier "cache"
seulement, sur mon iphone, en mode portrait, les images générées font 1024px de largeur, alors qu'elles devraient en principe mesurer 320px, non ? Je dois en fait basculer l'iphone en mode paysage pour générer des images de 320px de largeur...
bref, si vous pouviez me dire comment modifier certains paramètres pour corriger cette anomalie, ou peut-être me proposer une autre solution me permettant d'optimiser l'affichage de mes images et accélerer la performance de mon site. par avance, merci

Mammouth du PHP | 571 Messages

25 mars 2014, 14:53

bonjour,

Grâce aux médias queries tu peux cibler les images destinées à être affichées sur un terminal mobile ou sur un pc bien sûr en fonction de la taille de l'écran.Par exemple tu peux cibler les écrans dont la largeur est supérieure ou égale 768px(ex:iphone, s4) et dans ce cas préçis tu masques toutes les images de grande taille:
<div class="mobile">
  
  <h1>Mobile detecté</h1>
  <img src="City_Flow.jpg" width="320" height="250" alt="Image destinée au mobile">
  <p>ce bloc div sera affiché que sur smartphone</p>
</div>

<div class="pc">
  
  <h1>Grand écran detecté</h1>
  <img src="Rican.jpg" width="600" height="450" alt="image destinée au pc">
   <p>ce bloc div sera affiché que sur pc</p>
</div>
et puis dans ton fichier css:
@media screen and (min-width: 1024px){
  
.mobile{
 display:none; 
}
}

@media screen and (max-width: 768px){
  
.pc{
 display:none; 
}
}
voici ce que ça donne :responsive design

Par ailleurs Bootstrap 3 pouvait te faciliter grandement la tâche

Eléphanteau du PHP | 26 Messages

25 mars 2014, 15:04

salut, je te remercie pour cette réponse, je connais déjà cette solution, je ne suis pas sûr qu'elle me convienne vraiment, je cherche en fait une solution orientée php avec un peu de javascript peut-être. Pas certain que le display none rende mon site plus rapide, enfin j'ai lu récemment que cette propriété ne résolvait pas les problèmes de vitesse, que cette solution était trop employée par commodité etc. En dernier recours, je devrais sans doute l'adopter. Encore merci

mais si quelqu'un à une solution en php ou est capable de solutionner mon problème, je serai ravi, vraiment

Mammouth du PHP | 571 Messages

25 mars 2014, 18:10

J'ai cru comprendre que sur Iphone ton navigateur affichait des images de grande taille. D'où ma proposition d'utiliser les médias queries pour restituer une image(ou tout autre élément) beaucoup plus adaptée au terminal(smartphone, tablette, pc) car display: none retire l'élément du flux ce qui empêche le navigateur de l'afficher donc tu y gagnes en rapidité.

L'une des solutions PHP la plus utilisée est mobile detect.le principe ici est de détecter le terminal de l'internaute puis faire un traitement en fonction du terminal.Par exemple:
require_once 'Mobile_Detect.php';
$detect = new Mobile_Detect;
 
//le divice est un mobile 
if ( $detect->isMobile() ) {
 //afficher une div adaptée au mobile
}
 
// le device est une tablette
if( $detect->isTablet() ){
 //afficher une div adaptée aux tablettes
Pas certain que le display none rende mon site plus rapide, enfin j'ai lu récemment que cette propriété ne résolvait pas les problèmes de vitesse, que cette solution était trop employée par commodité etc
Tu peux effectuer des testes de performance pour déterminer laquelle des solutions est plus rapide avec des outils comme Ysow, google speed ou apache ab.

Eléphanteau du PHP | 26 Messages

25 mars 2014, 19:46

la solution mobile-detect est intéressante
si je l'utilise pour une redirection vers un index.php adapté au mobiles (un clone de l'index de base mais avec des chemins différents pour les images optimisées pour smartphone), cette solution te semble-t-elle correcte ? encore merci pour tous ces conseils, j'y vois nettement plus clair là.

Eléphanteau du PHP | 26 Messages

27 mars 2014, 17:43

finalement, j'opte pour une redirection

je comptais utiliser la classe mobile-detect disponible ici

mais ça ne marche pas...

j'ajoute ce code au tout début de ma page index.php :
<?php
require_once 'Mobile-Detect-2.7.9/Mobile_Detect.php';
$detect = new Mobile_Detect;
$isPhone = $detect->isMobile() && !$detect->isTablet();
if ( $detect->isMobile() ) {
header('http://m.monsite.com', true, 301);
}
?>
je peux indiquer n'importe quelle adresse en guise de header, la redirection ne se fait pas, auriez-vous une solution ?

merci

Mammouth du PHP | 571 Messages

27 mars 2014, 19:10

il te manque le mot Location dans la fonction header

header('Location: http://m.monsite.com',true,301);
exit;

Eléphanteau du PHP | 26 Messages

27 mars 2014, 19:29

oui, et puis je m'étais planté dans mon adresse locale...

http://192.168.1.58:8888etc
et pas localhost:8888

je vais clore ce sujet alors, merci à toi yann pour ton aide

Eléphanteau du PHP | 26 Messages

27 mars 2014, 22:25

nouveau problème...

j'aimerai afficher mes images en utilisant mobile-detect, avec une condition (si c'est un iphone ou pas)
<?php
if ( $detect->isMobile() ) {
afficher les images optimisées iphone
}  
else {
afficher les images standard
}
?>

j'ai donc ce code qui affiche les images provenant d'une base de données, mais je n'arrive pas à l'intégrer à la condition if else...
<?php    
$tableau_vignettes = explode("|",trim($donnees['UR_1180x787']));
for ($i = 0; $i < count($tableau_vignettes); $i++) {
  if (!empty($tableau_vignettes[$i])) {
  ?>
  <div class="image">
      <div class="inner">
        <img src="galeries/1180/<?php echo $tableau_vignettes[$i]; ?>"  />
     </div>    
   </div>
<?php
  }
}
?>