Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: skalowanie obrazków w wersji zaawansowanej
Forum PHP.pl > Forum > PHP
Black-Berry
Napisałem funkcję do skalowania obrazków. Idea polega na tym:
-->można podać wysokość i szerokość obrazka docelowego jako liczbę lub "auto"
-->można podać jedną z opcji "fill" "crop" lub "auto"
-->podanie wymiaru jako "auto" oznacza automatyczne wskoczenie do trybu "auto" (chyab nie da sie inaczej)
-->obrazki nigdy nie są zwiększane; mogą być tylko zmniejszane
-->wolne przestrzenie wypełniane są białym tłem
-->podajemy $_MAX_WIDTH_ i $_MAX_HEIGHT_ oznaczające maksymalne wymiary (to chyba jest najtrudniejsze bo obrazek docelowy nie powinien przekraczac tych wartości)

Przy testach z opcją "fill" i "crop" działa poprawnie. Przy opcji "auto" są jeszcze małe bugi. Moze by się komuś chciało z tym pobawić i dopomóc (choć pewnie nie). Za testy też byłbym wdzięczny.
  1. <?php
  2. /**
  3. * The $a_mode argumant can be "fill", "crop", "auto"[default mode];
  4. * Parameters $a_width and $a_height can be "0" or "auto" (the "auto" mode is triggered on then);
  5. */
  6. function create_resampled_image( $a_source_file, $a_destination_file, $a_width, $a_height, $a_mode="auto" )
  7. {
  8. $_MAX_WIDTH_ = 640;
  9. $_MAX_HEIGHT_ = 480;
  10.  
  11. list( $source_width, $source_height ) = getimagesize( $a_source_file );
  12. if( !$a_width ) $a_width = "auto";
  13. if( !$a_height ) $a_height = "auto";
  14. if( $a_width == "auto" or $a_height == "auto" ) $a_mode = "auto";
  15.  
  16.  
  17. switch( $a_mode )
  18. {
  19. case "fill": #no mistakes found
  20. if( $a_width >= $_MAX_WIDTH_ and $a_height >= $_MAX_HEIGHT_ ){
  21. $a_width = $_MAX_WIDTH_;
  22. $a_height = $_MAX_HEIGHT_;
  23. $dest_height = $source_height;
  24. $dest_width = $source_width;
  25. }elseif( $a_width >= $_MAX_WIDTH_ ){
  26. $a_width = $_MAX_WIDTH_;
  27. $dest_height = $source_height;
  28. $dest_width = $source_width;
  29. }elseif( $a_height >= $_MAX_HEIGHT_ ){
  30. $a_height = $_MAX_HEIGHT_;
  31. $dest_height = $source_height;
  32. $dest_width = $source_width;
  33. }
  34.  
  35. if( ( $a_height/$source_height ) > ( $a_width/$source_width ) )
  36. {  
  37. $dest_width = $a_width;
  38. $dest_height = ($dest_width/$source_width)*$source_height;
  39. $dest_left = 0;
  40. $dest_top = ( $a_height - $dest_height ) / 2;
  41. }else{
  42. $dest_width = ($a_height/$source_height)*$source_width;
  43. $dest_height = $a_height;
  44. $dest_left = ( $a_width - $dest_width ) / 2;
  45. $dest_top = 0;
  46. }
  47. if( $dest_width > $source_width ){
  48. $dest_width = $source_width;
  49. $dest_left = ( $a_width - $dest_width ) / 2;
  50. }
  51. if( $dest_height > $source_height ){
  52. $dest_height = $source_height;
  53. $dest_top = ( $a_height - $dest_height ) / 2;
  54. }
  55. break;
  56. case "crop": #no mistakes found 
  57. if( $a_width >= $_MAX_WIDTH_ and $a_height >= $_MAX_HEIGHT_ ){
  58. $a_width = $_MAX_WIDTH_;
  59. $a_height = $_MAX_HEIGHT_;
  60. $dest_height = $source_height;
  61. $dest_width = $source_width;
  62. }elseif( $a_width >= $_MAX_WIDTH_ ){
  63. $a_width = $_MAX_WIDTH_;
  64. $dest_height = $source_height;
  65. $dest_width = $source_width;
  66. }elseif( $a_height >= $_MAX_HEIGHT_ ){
  67. $a_height = $_MAX_HEIGHT_;
  68. $dest_height = $source_height;
  69. $dest_width = $source_width;
  70. }
  71.  
  72. if( ( $a_height/$source_height ) > ( $a_width/$source_width ) ){  
  73. $dest_width = ($a_height/$source_height)*$source_width;
  74. $dest_height = $a_height;
  75. $dest_left = ( $a_width - $dest_width ) / 2;
  76. $dest_top = 0;
  77. }else{
  78. $dest_width = $a_width;
  79. $dest_height = ($a_width/$source_width)*$source_height;
  80. $dest_left = 0;
  81. $dest_top = ( $a_height - $dest_height ) / 2;
  82. }
  83.  
  84. if( $dest_width > $source_width ){
  85. $dest_width = $source_width;
  86. $dest_left = ( $a_width - $dest_width ) / 2;
  87. }
  88.  
  89. if( $dest_height > $source_height ){
  90. $dest_height = $source_height;
  91. $dest_top = ( $a_height - $dest_height ) / 2;
  92. }
  93. break;
  94. case "auto": #try to change this in future
  95. if( $a_width == "auto" and $a_height == "auto" )
  96. {  
  97. $dest_width = $source_width;
  98. $dest_height = $source_height;
  99. $a_width = $dest_width;
  100. $a_height = $dest_height;
  101. $dest_left = 0;
  102. $dest_top = 0;
  103. }elseif( $a_width == "auto" ){
  104. $dest_width = ($a_height/$source_height)*$source_width;
  105. $dest_height = $a_height;
  106. $dest_left = 0;
  107. $dest_top = 0;
  108. $a_width = $dest_width;
  109. } else{
  110. $dest_width = $a_width;
  111. $dest_height = ($a_width/$source_width)*$source_
  112. $dest_top = 0;
  113. $a_height = $dest_height;
  114. }
  115. if( $a_width >= $_MAX_WIDTH_ and $a_height >= $_MAX_HEIGHT_ ){
  116. $a_width = $_MAX_WIDTH_;
  117. $a_height = $_MAX_HEIGHT_;
  118. $dest_height = ($a_width/$_MAX_WIDTH_)*$_MAX_HEIGHT_;
  119. $dest_width = ($a_height/$_MAX_HEIGHT_)*$_MAX_WIDTH_;
  120. }elseif( $a_width >= $_MAX_WIDTH_ ){
  121. $a_width = $_MAX_WIDTH_;
  122. $dest_height = $source_height;
  123. $dest_width = ($a_height/$source_height)*$source_width;
  124. }elseif( $a_height >= $_MAX_HEIGHT_ ){
  125. $a_height = $_MAX_HEIGHT_;
  126. $dest_height = $_MAX_HEIGHT_;
  127. $dest_width = ($a_height/$source_height)*$source_width;
  128. }
  129. $dest_left = ( $a_width - $dest_width ) / 2;
  130. $dest_top = ( $a_height - $dest_height ) / 2;
  131. break;
  132. }
  133.  
  134. $mime_type = file_mime_type( $a_source_file );
  135. $src_image = imagecreatefromjpeg( $a_source_file );
  136. $dst_image = imagecreatetruecolor( $a_width, $a_height );
  137. $background = ImageColorAllocate( $dst_image, 255, 255, 255 );
  138. ImageFill( $dst_image, 0, 0, $background 
  139. imagecopyresampled( $dst_image, $src_image, $dest_left, $dest_top, 0, 0, $dest_width, $dest_height, $source_width, $source_height ); 
  140. imagejpeg( $dst_image, $a_destination_file 
  141. imagedestroy( $dst_image );
  142. imagedestroy( $src_image );
  143. }
  144. ?>


i jeszcze funkcja mime type:

  1. <?php
  2. function file_mime_type( $a_file )
  3. {
  4. if( function_exists(finfo_open) )
  5. {
  6. $handle = finfo_open( FILEINFO_MIME );
  7. $mime_type = finfo_file( $handle, $a_file );
  8. finfo_close( $handle );
  9. return $mime_type;
  10. }
  11. else if( function_exists(mime_content_type) )
  12. {
  13. return mime_content_type($a_file);
  14. }else{
  15. die( _SYSTEM_NO_MIME_READER_AVALIBLE_ );
  16. }
  17. }
  18. ?>
l0ud
Daj jakiś konkretny przykład występowania błędu przy opcji "auto".
Black-Berry
"auto" działa ok ale jak podasz wymiar obrazka wiekszy niż MAX to przy niektórych wielkościach obrazków nie trzyma skali. Wywołanie z opcjami np ("auto", 900, "auto"). Strasznie dużo warunkó jest i sie przy tym gubię.
l0ud
Ale czego spodziewasz się na wyjściu przy opcji auto? Co to jest $a_width i $a_height skoro później deklarujesz $_MAX_WIDTH_ i $_MAX_HEIGHT_ ? Trochę nie rozumiem koncepcji tego kodu...
Black-Berry
Chodzi o to ze masz zadeklarowaną maksymalną wysokosc i szerokosc jaką moze przyjąc obrazek.
--> podajac np. wartosc w=300 h=auto z obrazka 600x400 generuje sie obrazek o w=300 h=200
--> problem pojawia sie kiedy wpisujesz np w=300 h=auto dla obrazka 600x1600 bo 1600:2 == 800 >= h_max. Wtedy powinien sie wygenerowac obrazek niższy. Takich kombinacji jest wiecej dlatego to takie zagmatwane
--> dobrze jest jednak miec pewnosc ze user nie wygeneruje zbyt duzego obrazka w zadnym przypadku.

może jeszcze dodam kilka ogólnych założeń:
--> z opcją "crop" chcesz mieć ujęcie środka obrazka możliwie bez białych pól (starasz sie też zminiejszyc obrazek trochę aby jak najwiecej z niego nie zostało obcięte)
--> z opcją "fill" chcesz mieć cały obrazek widoczny w danym prostokącie ( pojawiają sie białe pola na bokach )
--> z opcją auto chcesz mieć cały obrazek bez białych obramowań i obcinania, a nie chcesz myslec dużo o tym co powstanie smile.gif
l0ud
W funkcji było kilka błędów które powodowały parse error'y. (obcięte linie, chyba coś źle wkleiłeś?)
Poprawiłem je i napisałem procedurę dla 'auto' od nowa winksmiley.jpg Mam nadzieję że zrozumiałem, o co Ci chodziło w działaniu.

http://twojkod.pl/kod.php?id=36
[opcja pobierz plik, forum nie chciało przyjąć tak długiego posta]

Btw, po co Ci sprawdzanie mime, skoro tego później nie wykorzystujesz? Pomijam fakt, że domyślnie PHP nie ma takich funkcji smile.gif
Black-Berry
@l0ud Rządzisz! Przeprowadziłem serię testów. Wszystko działa świetnie.

Jeśli chodzi o "mime_type" to w orginale mam jeszcze sprawdzanie mime i converter z plików BMP, ale forum nie przyjmuje tak długich postów. Gdybyś mógł wstawić to tam gdzie Twój kod to wysłałbym Ci na maila całość. Byłoby dla potomności.

Teraz wystarczy dorobić to tego jakiś 'fancy' upload panel i będzie mozna zrobić ładny plugin np do TinyMce.

Pozdrawiam.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.