Динамическое изменение размеров изображения. Вывод увеличенной части изображения с помощью PHP функций.

Довольно часто приходится выводить изображение в ограниченной области. Стандартными средствами HTML этого не составляет труда. Теперь допустим, что изображение имеет большие размеры. Соответственно размеры файла этого изображения могут быть довольно большими. Передача такого файла клиенту может вызвать некоторые затруднения, к тому же увеличить трафик. Конечно можно уменьшить размеры изображения и хранить на сервере уже маленький рисунок. А если будет необходима его увеличенная копия? Что делать в такой ситуации? К счастью, с помощью функций PHP можно изменить размеры исходной картинки на лету и отправить клиенту уже приведенную к требуемым размерам картинку. Кроме этого, можно отобразить только часть исходного изображения.

Задача:
Требуется отобразить исходно изображение произвольного размера в области 400 х 400. При первом щелчке мыши по изображению отобразить часть исходной картинки увеличенной в 2 раза по сравнению с изображением, которое было вписано в область 400х400. При этом необходимо вывести ту часть картинки, по которому был сделан щелчок. При втором щелчке мыши снова отобразить исходную картинку вписанную в область. И так по кругу, отображая либо всю исходную картинку, либо ее часть.

Решение:
Решение этой задачи осуществляется с помощью двух сценариев – image.php и getimg.php.
image.php – определяет координаты щелчка с помощью java script, и выводит в область изображение. Изображение выводится с помощью конструкции

<img src="getimg.php?file=<?php echo $file; ?>&x=<?php echo $x;?>&y=<?php echo $y;?>&flag=<?php echo $flag;?>">

Чтобы было понятнее, упроченный вариант этой конструкции буде выглядеть так

<img src="getimg.php">

Т.е. вместо загрузки файла картинки он будет обращаться ко второму сценарию. А все что после «?» - это передача параметров.
getimg.php – обрабатывает картинку и возвращает требуемый результат. В зависимости от значения флага, результатом будет либо вся картинка, либо ее часть.

Image.php

  1. <?php
  2.  
  3. //определяем входные параметры
  4. $string = $string.$_SERVER['QUERY_STRING'];
  5.  
  6. if ($string == "")
  7. {
  8. $file = "001"; //имя файла JPG избражения без расширения
  9. $x = 0; //координата Х
  10. $y = 0; //координата Y
  11. $flag = 0; //флаг увеличения
  12. }
  13. else
  14. {
  15. parse_str( $string, $st);
  16. $file = $st[file];
  17. $x=$st[x];
  18. $y=$st[y];
  19. $flag = $st[flag];
  20. }
  21.  
  22. //java скрипт определения координаты щелчка мыши
  23. //и загрузки этой же страницы с новыми координатами щелчка
  24. ?>
  25. <script>
  26. function test(mouseEvent) {
  27.  
  28. if (!mouseEvent) mouseEvent = window.event;
  29.  
  30. var sourceElement = (mouseEvent.target)?mouseEvent.target:mouseEvent.srcElement;
  31. <?php //координата Х щелчка мыши ?>
  32. var x = mouseEvent.clientX - sourceElement.offsetLeft;
  33. <?php //координата Y щелчка мыши ?>
  34. var y = mouseEvent.clientY - sourceElement.offsetTop;
  35. flag = <?php echo $flag.";" ?>
  36. <?php //меняем флаг ?>
  37. if (flag > 0){ flag = 0 }else { flag = 1 };
  38. <?php //загрузка этой же страницы с новыми координатами и флагом ?>
  39. var adr = "image.php?file=<?php echo $file; ?>&x="+ x + "&y="+ y + "&flag="+ flag;
  40. window.location.href=adr;
  41.  
  42. }
  43. <?php //функция инициализации ?>
  44. function init() {
  45. document.getElementById("image").onclick = test;
  46. }
  47. </script>
  48. <body onload="init();">
  49. <div id="image" style="width: 400px; height: 400px;">
  50. <?php //запуск сценария вывода изображения ?>
  51. <img src="getimg.php?file=<?php echo $file; ?>&x=<?php echo $x;?>&y=<?php echo $y;?>&flag=<?php echo $flag;?>">
  52. </div>
  53. </body>
  54.  
  55. getimg.php
  56. <?php
  57. // определяем с каким типом изображения будем работать
  58. header("Content-type: image/jpeg");
  59. //создаем конечное изображение и заполняем его фоновым цветом
  60. $res = imageCreateTrueColor(400,400);
  61. $col = imageColorAllocate($res, 200, 255, 200);
  62. imageFilledRectangle($res, 0, 0, 400, 400, $col);
  63.  
  64. //определяем входные параметры
  65. $string = $_SERVER['QUERY_STRING'];
  66. parse_str( $string, $st);
  67. $imgfile = $st[file].".jpg";
  68. //загружаем исходное изображение
  69. $img = imagecreatefromjpeg($imgfile);
  70.  
  71. //определяем ширину и высоту изображений с учетом пропорций
  72. //исходного изображения
  73. //lx, ly - размеры изображения, которое вписалось бы в квадрат 400*400
  74. //l2x, l2y - размеры изображения, которое вписалось бы в квадрат 800*800
  75. if (imagesx($img) > imagesy($img))
  76. {
  77. $lx = 400; $ly = (400*imagesy($img))/imagesx($img);
  78. $l2x = 800; $l2y = (800*imagesy($img))/imagesx($img);
  79. }
  80. else
  81. {
  82. $ly = 400; $lx = (400*imagesx($img))/imagesy($img);
  83. $l2y = 800; $l2x = (800*imagesx($img))/imagesy($img);
  84. }
  85.  
  86. //создаем изображение размером lx*ly и вписываем туда исходное
  87. $res1 = imageCreateTrueColor($lx,$ly);
  88. imagecopyresized ($res1,$img,0,0,0,0,$lx,$ly,imagesx($img),imagesy($img));
  89.  
  90. //создаем изображение размером l2x*l2y и вписываем туда исходное
  91. $res2 = imageCreateTrueColor($l2x,$l2y);
  92. imagecopyresized ($res2,$img,0,0,0,0,$l2x,$l2y,imagesx($img),imagesy($img));
  93.  
  94. //В зависимости от значения флага в конечное изображение вставляем
  95. //либо всю исходную картинку преобразованную до размеров lx*ly
  96. //либо часть исходной картинки преобразованной до размеров l2x*l2y
  97. if ($st[flag] == 0)
  98. {
  99. imagecopy ($res,$res1,(400-$lx)/2,(400-$ly)/2,0,0,$lx,$ly);
  100. }
  101. else
  102. {
  103. //определяем координаты вставляемого изображения в зависимости от
  104. //координат щелчка мыши
  105. $x = 2*$st[x]-(800-$l2x)/2-200;
  106. $y = 2*$st[y]-(800-$l2y)/2-200;
  107. // учитываем, чтобы копируемый участок не выходил за пределы изображения
  108. if ($x < 0){$x = 0;}
  109. if ($x > $l2x-400){$x = $l2x-400;}
  110. if ($y < 0){$y = 0;}
  111. if ($y > $l2y-400){$y = $l2y-400;}
  112.  
  113. //копируем часть увеличенной картинки
  114. imagecopy ($res,$res2,0,0,$x,$y,400,400);
  115. }
  116. //выводим полученный результат
  117. imagepng($res);
  118. ?>

Комментарии в сценариях изложены доходчиво, поэтому на разборе останавливаться не будем.
Замечание:
Следует учесть, что координаты щелчка определяются относительно всего документа, а не относительно области. Чтобы исправить это, необходимо дополнительно определить координаты области относительно документа и с помощью нехитрых математических вычислений определить требуемые координаты относительно области.
Если ввести еще несколько параметров и немного изменив сценарий можно добиться многократного увеличения и пошагового уменьшения.