Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> skalowanie obrazków w wersji zaawansowanej
Black-Berry
post 24.02.2008, 14:35:34
Post #1





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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. ?>


--------------------
Go to the top of the page
+Quote Post
l0ud
post 24.02.2008, 14:46:32
Post #2





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

Ostrzeżenie: (0%)
-----


Daj jakiś konkretny przykład występowania błędu przy opcji "auto".


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Black-Berry
post 24.02.2008, 15:08:12
Post #3





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

Ostrzeżenie: (0%)
-----


"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ę.


--------------------
Go to the top of the page
+Quote Post
l0ud
post 24.02.2008, 16:44:34
Post #4





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

Ostrzeżenie: (0%)
-----


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...


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Black-Berry
post 24.02.2008, 18:38:14
Post #5





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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

Ten post edytował Black-Berry 24.02.2008, 18:42:21


--------------------
Go to the top of the page
+Quote Post
l0ud
post 24.02.2008, 21:57:27
Post #6





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

Ostrzeżenie: (0%)
-----


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


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Black-Berry
post 24.02.2008, 23:21:24
Post #7





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@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.


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 06:26