📜 ⬆️ ⬇️

Preview and Resize pictures on the fly

I reworked the site for the customer on Netcat and was surprised to find that someone else uses the download of separate images for originals and for thumbnails and, as a result, separate columns in the database table. Where it was not going to create thumbnails on the server side after loading the original.

The idea is simple and not new. With this approach, I first encountered in UMI-CMS, and used it in RubyOnRails. The point is that previews are created only when they are needed and of any size, and only the name of the original is stored in the database.

If you need to display a preview of a picture, you call a function like:
  1. @thumbs = Photo. view_thumbs ( 'originals_name_file.jpg' , '100' , 'auto' )
where the second and the third parameter is the desired size in pixels (auto means auto-fit to the scale).
')
The view_thumbs method checks in the folder (for example, "/ images / cache") the presence of the file originals_name_file_100xauto.jpg. If it finds, it returns the string “originals_name_file_100xauto.jpg”, if it does not find it, it creates a file of the required size on the fly and returns the same.

The advantages of the approach are obvious:
  1. There is no garbage in the form of a large number of thumbnails on the disk. All previews are stored in one “cache” folder and can be periodically deleted to free up space.
  2. Unlimited number of thumbnails of different sizes. It is enough to set the necessary parameters in the method.
For cakePHP there is a helper images.php which can be pulled out of Bakesale (there is no automatic fitting). Below is a method on RubyOnRails that implements this approach.

  1. require 'RMagick'

  2. class Photo < ActiveRecord :: Base

  3. def self . view_thumbs ( image, width = 'auto' , height = 'auto' )
  4. img_arr = image. split ( "." )
  5. img, img_type = img_arr [ 0 ] , img_arr [ 1 ]

  6. img_thumbs = "# {img} _ # {width} x # {height}"
  7. img_main_dir = "# {RAILS_ROOT} / public / images /"
  8. img_thumbs_dir = "# {RAILS_ROOT} / public / images / cache /"

  9. begin
  10. img_thumbs = Magick :: Image . read ( "# {img_thumbs_dir} / # {img_thumbs}. # {img_type}" )
  11. rescue Magick :: ImageMagickError # All the salt is here. If there is no necessary thumbs, then after reading the error falls out, which we save. If everything is ok, then the code is not executed further.
  12. img_orig = Magick :: Image . read ( "# {img_main_dir} / # {image}" ) . first
  13. img_size = { : main => { : cols => img_orig. columns ,: rows => img_orig. rows }
  14. : thumb => { : cols => 0.0 ,: rows => 0.0 }
  15. }
  16. if 'auto' == width and 'auto' == height
  17. img_size [ : thumb ] [ : rows ] = img_size [ : main ] [ : rows ]
  18. img_size [ : thumb ] [ : cols ] = img_size [ : main ] [ : cols ]
  19. end
  20. if 'auto' ! = width and 'auto' == height
  21. img_size [ : thumb ] [ : rows ] = ( ( width. to_f / img_size [ : main ] [ : cols ] ) * img_size [ : main ] [ : rows ] ) . to_i
  22. img_size [ : thumb ] [ : cols ] = width. to_i
  23. end
  24. if 'auto' == width and 'auto' ! = height
  25. img_size [ : thumb ] [ : rows ] = height. to_i
  26. img_size [ : thumb ] [ : cols ] = ( ( height. to_f / img_size [ : main ] [ : rows ] ) * img_size [ : main ] [ : cols ] ) . to_i
  27. end
  28. if 'auto' ! = width and 'auto' ! = height
  29. img_size [ : thumb ] [ : rows ] = height. to_i
  30. img_size [ : thumb ] [ : cols ] = width. to_i
  31. end

  32. img_new = img_orig. resize ! ( img_size [ : thumb ] [ : cols ] . to_i , img_size [ : thumb ] [ : rows ] . to_i )
  33. img_new. write "# {img_thumbs_dir} / # {img_thumbs}. # {img_type}"
  34. end
  35. img_thumbs = x
  36. Return "# {img_thumbs}. # {img_type}"
  37. end
  38. end

Practice shows that specifying only one size in a method with automatic fitting of another is not enough. If you limit only to the width, then the picture will certainly fall too high and the whole layout can move out. The same with height. And in the above code, if you specify both the height and width of the resize will be without saving the scale. Below is a piece of code on php that implements a resize with constraint in both height and width while preserving the scale.

  1. $ img_size = array (
  2. 'main' => array ( 'width' => imagesx ( $ img_src ) , 'height' => imagesy ( $ img_src ) ) ,
  3. 'thumb' => array ( 'width' => 0 , 'height' => 0 )
  4. ) ;

  5. if ( 'auto' == $ width && 'auto' == $ height ) {
  6. $ img_size [ 'thumb' ] [ 'height' ] = ( int ) $ img_size [ 'main' ] [ 'height' ] ;
  7. $ img_size [ 'thumb' ] [ 'width' ] = ( int ) $ img_size [ 'main' ] [ 'width' ] ;
  8. }
  9. else if ( 'auto' ! = $ width && 'auto' == $ height ) {
  10. $ img_size [ 'thumb' ] [ 'width' ] = ( ( $ img_size [ 'main' ] [ 'width' ] <= $ width ) ? $ img_size [ 'main' ] [ 'width' ] : $ width ) ;
  11. $ img_size [ 'thumb' ] [ 'height' ] = ( int ) round ( ( $ img_size [ 'thumb' ] [ 'width' ] / $ img_size [ 'main' ] [ 'width' ] ) * $ img_size [ ' main ' ] [ ' height ' ] ) ;
  12. }
  13. else if ( 'auto' == $ width && 'auto' ! = $ height ) {
  14. $ img_size [ 'thumb' ] [ 'height' ] = ( ( $ img_size [ 'main' ] [ 'height' ] <= $ height ) ? $ img_size [ 'main' ] [ 'height' ] : $ height ) ;
  15. $ img_size [ 'thumb' ] [ 'width' ] = ( int ) round ( ( $ height / $ img_size [ 'main' ] [ 'height' ] ) * $ img_size [ 'main' ] [ 'width' ] ) ;
  16. }
  17. else if ( 'auto' ! = $ width && 'auto' ! = $ height ) {
  18. $ img_size [ 'thumb' ] [ 'height' ] = ( ( $ img_size [ 'main' ] [ 'height' ] <= $ height ) ? $ img_size [ 'main' ] [ 'height' ] : $ height ) ;
  19. $ img_size [ 'thumb' ] [ 'width' ] = ( ( $ img_size [ 'main' ] [ 'width' ] <= $ width ) ? $ img_size [ 'main' ] [ 'width' ] : $ width ) ;
  20. $ Kt = $ img_size [ 'thumb' ] [ 'height' ] / $ img_size [ 'thumb' ] [ 'width' ] ; // 5/1
  21. $ Km = $ img_size [ 'main' ] [ 'height' ] / $ img_size [ 'main' ] [ 'width' ] ; // 5/1

  22. if ( $ Kt > $ Km ) {
  23. $ img_size [ 'thumb' ] [ 'height' ] = $ img_size [ 'thumb' ] [ 'width' ] * $ Km ;
  24. }
  25. else if ( $ Kt < $ Km ) {
  26. $ img_size [ 'thumb' ] [ 'width' ] = $ img_size [ 'thumb' ] [ 'height' ] / $ Km ;
  27. }
  28. }
______________________
The text was prepared in the Habr Editor from © SoftCoder.ru

Source: https://habr.com/ru/post/53912/


All Articles