Method: TCPDF#Image

Defined in:
lib/tcpdf.rb

#Image(file, x = '', y = '', w = 0, h = 0, type = '', link = nil, align = '', resize = false, dpi = 300, palign = '', ismask = false, imgmask = false, border = 0, fitbox = false, hidden = false, fitonpage = false) ⇒ Object Also known as: image

Puts an image in the page. The upper-left corner must be given. The dimensions can be specified in different ways:

  • explicit width and height (expressed in user unit)

  • one explicit dimension, the other being calculated automatically in order to keep the original proportions

  • no explicit dimension, in which case the image is put at 72 dpi

Supported formats are PNG images whitout RMagick library and JPEG and GIF images supported by RMagick. For JPEG, all flavors are allowed:

  • gray scales

  • true colors (24 bits)

  • CMYK (32 bits)

For PNG, are allowed:

  • gray scales on at most 8 bits (256 levels)

  • indexed colors

  • true colors (24 bits)

If a transparent color is defined, it will be taken into account (but will be only interpreted by Acrobat 4 and above). The format can be specified explicitly or inferred from the file extension. It is possible to put a link on the image.

  • Remark: if an image is used several times, only one copy will be embedded in the file.

@param string :file

Name of the file containing the image.

@param float :x

Abscissa of the upper-left corner.

@param float :y

Ordinate of the upper-left corner.

@param float :w

Width of the image in the page. If not specified or equal to zero, it is automatically calculated.

@param float :h

Height of the image in the page. If not specified or equal to zero, it is automatically calculated.

@param string :type

Image format. Possible values are (case insensitive): JPG, JPEG, PNG. If not specified, the type is inferred from the file extension.

@param mixed :link

URL or identifier returned by AddLink().

@param string :align

Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:

  • T: top-right for LTR or top-left for RTL

  • M: middle-right for LTR or middle-left for RTL

  • B: bottom-right for LTR or bottom-left for RTL

  • N: next line

@param mixed :resize

If true resize (reduce) the image to fit :w and :h (requires RMagick library); if false do not resize; if 2 force resize in all cases (upscaling and downscaling).

@param int :dpi

dot-per-inch resolution used on resize

@param string :palign

Allows to center or align the image on the current line. Possible values are:

  • L : left align

  • C : center

  • R : right align

  • ” : empty string : left for LTR or right for RTL

@param boolean :ismask

true if this image is a mask, false otherwise

@param mixed :imgmask

image object returned by this function or false

@param mixed :border

Indicates if borders must be drawn around the image. The value can be either a number:

  • 0: no border (default)

  • 1: frame

or a string containing some or all of the following characters (in any order):

  • L: left

  • T: top

  • R: right

  • B: bottom

@param boolean :fitbox

If true scale image dimensions proportionally to fit within the (:w, :h) box.

@param boolean :hidden

if true do not display the image.

@param boolean :fitonpage

if true the image is resized to not exceed page dimensions.

@return

image information

@access public
@since 1.1


4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
# File 'lib/tcpdf.rb', line 4713

def Image(file, x='', y='', w=0, h=0, type='', link=nil, align='', resize=false, dpi=300, palign='', ismask=false, imgmask=false, border=0, fitbox=false, hidden=false, fitonpage=false)
  w = 0 if w == ''
  h = 0 if h == ''

  x = @x if x == ''
  y = @y if y == ''

  # set bottomcoordinates
  @img_rb_y = y + h
  Error('Image filename is empty.') if file.nil? or file.length == 0

  # get image dimensions
  imsize = getimagesize(file)
  if imsize.nil? or imsize == false
    # encode spaces on filename
    file = file.gsub(' ', '%20')
    imsize = getimagesize(file)

    if imsize.nil?
      Error('Missing image file: ' + file)
    elsif imsize == false
      if (w > 0) and (h > 0)
        pw = getHTMLUnitToUnits(w, 0, @pdfunit, true) * @img_scale * @k
        ph = getHTMLUnitToUnits(h, 0, @pdfunit, true) * @img_scale * @k
        imsize = [pw, ph]
      else
        Error('[Image] Unable to get image width and height: ' + file)
      end
    end
  end
  # get original image width and height in pixels
  pixw = imsize[0]
  pixh = imsize[1]

  # calculate image width and height on document
  if (w <= 0) and (h <= 0)
    # convert image size to document unit
    w = pixelsToUnits(pixw)
    h = pixelsToUnits(pixh)
  elsif w <= 0
    w = h * pixw / pixh
  elsif h <= 0
    h = w * pixh / pixw
  elsif fitbox and (w > 0) and (h > 0)
    # scale image dimensions proportionally to fit within the (:w, :h) box
    if ((w * pixh) / (h * pixw)) < 1
      h = w * pixh / pixw
    else
      w = h * pixw / pixh
    end
  end

  # resize image to be contained on a single page          # fix at page break case.
  if fitonpage
    ratio_wh = w / h
    if (@t_margin + h) > @page_break_trigger
      h = @page_break_trigger - @t_margin
      w = h * ratio_wh
    end
    if !@rtl and ((x + w) > (@w - @r_margin))
      w = @w - @r_margin - x
      h = w / ratio_wh
    elsif @rtl and ((x - w) < @l_margin)
      w = x - @l_margin
      h = w / ratio_wh
    end
  end

  # Check whether we need a new page first as this does not fit
  prev_x = @x
  if checkPageBreak(h, y)
    y = @y
    if @rtl
      x += prev_x - @x
    else
      x += @x - prev_x
    end
  end
  # resize image to be contained on a single page
  if fitonpage
    ratio_wh = w / h
    if (y + h) > @page_break_trigger
      h = @page_break_trigger - y
      w = h * ratio_wh
    end
    if !@rtl and ((x + w) > (@w - @r_margin))
      w = @w - @r_margin - x
      h = w / ratio_wh
    elsif @rtl and ((x - w) < @l_margin)
      w = x - @l_margin
      h = w / ratio_wh
    end
  end
  # calculate new minimum dimensions in pixels
  neww = (w * @k * dpi / @dpi).round
  newh = (h * @k * dpi / @dpi).round
  # check if resize is necessary (resize is used only to reduce the image)
  newsize = neww * newh
  pixsize = pixw * pixh
  if resize == 2
    resize = true
  elsif newsize >= pixsize
    resize = false
  end

  # check if image has been already added on document
  newimage = true
  if @imagekeys.include?(file)
    newimage = false;
    # get existing image data
    info = getImageBuffer(file)
    # check if the newer image is larger
    oldsize = info['w'] * info['h']
    if ((oldsize < newsize) and resize) or ((oldsize < pixsize) and !resize)
      newimage = true
    end
  end
  if newimage
    #First use of image, get info
    if (type == '')
      type = getImageFileType(file, imsize)
    else
      type.downcase!
      type = 'jpeg' if type == 'jpg'
    end

    info = false
    if !resize or !Object.const_defined?(:Magick)
      if (type == 'jpeg')
        info=parsejpeg(file)
      elsif (type == 'png')
        info=parsepng(file);
      elsif (type == 'gif')
        tmpFile = imageToPNG(file)
        info=parsepng(tmpFile.path)
        tmpFile.delete
      else
        #Allow for additional formats
        mtd='parse' + type;
        unless self.respond_to?(mtd, true)
          Error('Unsupported image type: ' + type);
        end
        info=send(mtd, file);
      end
      # not use
      #if info == 'pngalpha'
      #  return ImagePngAlpha(file, x, y, w, h, 'PNG', link, align, resize, dpi, palign)
      #end
    end
    if !info
      if Object.const_defined?(:Magick)
        # RMagick library

        ### T.B.D ### TCPDF 5.0.000 ###
        # if type == 'SVG'
        # else
          img = Magick::ImageList.new(file)
        # end
        if resize
          img.resize(neww,newh)
        end
        img.format = 'JPEG'
        tmpname = Tempfile.new(File::basename(file), @@k_path_cache)
        tmpname.binmode
        jpeg_quality = @jpeg_quality
        tmpname.print img.to_blob { self.quality = jpeg_quality }
        tmpname.close

        info = parsejpeg(tmpname.path)
        tmpname.delete
      else
        return false
      end
    end

    if info == false
      # If false, we cannot process image
      return false
    end
    if ismask
      # force grayscale
      info['cs'] = 'DeviceGray'
    end
    info['i'] = @numimages
    if !@imagekeys.include?(file)
      info['i'] += 1
    end
    if imgmask != false
      info['masked'] = imgmask
    end
    # add image to document
    setImageBuffer(file, info)
  end

  # set alignment
  @img_rb_y = y + h
  # set alignment
  if @rtl
    if palign == 'L'
      ximg = @l_margin
    elsif palign == 'C'
      ximg = (@w + @l_margin - @r_margin - w) / 2
    elsif palign == 'R'
      ximg = @w - @r_margin - w
    else
      ximg = x - w
    end
    @img_rb_x = ximg
  else
    if palign == 'L'
      ximg = @l_margin
    elsif palign == 'C'
      ximg = (@w + @l_margin - @r_margin - w) / 2
    elsif palign == 'R'
      ximg = @w - @r_margin - w
    else
      ximg = x
    end
    @img_rb_x = ximg + w
  end
  if ismask or hidden
    # image is not displayed
    return info['i']
  end
  xkimg = ximg * @k
  out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', w * @k, h * @k, xkimg, (@h -(y + h)) * @k, info['i']))

  if border != 0
    bx = x
    by = y
    @x = ximg
    if @rtl
      @x += w
    end
    @y = y
    Cell(w, h, '', border, 0, '', 0, '', 0)
    @x = bx
    @y = by
  end

  if link and !link.empty?
    Link(ximg, y, w, h, link)
  end

  # set pointer to align the successive text/objects
  case align
  when 'T'
    @y = y
    @x = @img_rb_x
  when 'M'
    @y = y + (h/2).round
    @x = @img_rb_x
  when 'B'
    @y = @img_rb_y
    @x = @img_rb_x
  when 'N'
    SetY(@img_rb_y)
  end
  @endlinex = @img_rb_x
  return info['i']
end