image.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package canvas
  2. import (
  3. "image"
  4. "io"
  5. "io/ioutil"
  6. "path/filepath"
  7. "fyne.io/fyne/v2"
  8. "fyne.io/fyne/v2/storage"
  9. )
  10. // ImageFill defines the different type of ways an image can stretch to fill its space.
  11. type ImageFill int
  12. const (
  13. // ImageFillStretch will scale the image to match the Size() values.
  14. // This is the default and does not maintain aspect ratio.
  15. ImageFillStretch ImageFill = iota
  16. // ImageFillContain makes the image fit within the object Size(),
  17. // centrally and maintaining aspect ratio.
  18. // There may be transparent sections top and bottom or left and right.
  19. ImageFillContain // (Fit)
  20. // ImageFillOriginal ensures that the container grows to the pixel dimensions
  21. // required to fit the original image. The aspect of the image will be maintained so,
  22. // as with ImageFillContain there may be transparent areas around the image.
  23. // Note that the minSize may be smaller than the image dimensions if scale > 1.
  24. ImageFillOriginal
  25. )
  26. // ImageScale defines the different scaling filters used to scaling images
  27. type ImageScale int32
  28. const (
  29. // ImageScaleSmooth will scale the image using ApproxBiLinear filter (or GL equivalent)
  30. ImageScaleSmooth ImageScale = iota
  31. // ImageScalePixels will scale the image using NearestNeighbor filter (or GL equivalent)
  32. ImageScalePixels
  33. // ImageScaleFastest will scale the image using hardware GPU if available
  34. //
  35. // Since: 2.0
  36. ImageScaleFastest
  37. )
  38. // Declare conformity with CanvasObject interface
  39. var _ fyne.CanvasObject = (*Image)(nil)
  40. // Image describes a drawable image area that can render in a Fyne canvas
  41. // The image may be a vector or a bitmap representation, it will fill the area.
  42. // The fill mode can be changed by setting FillMode to a different ImageFill.
  43. type Image struct {
  44. baseObject
  45. // one of the following sources will provide our image data
  46. File string // Load the image from a file
  47. Resource fyne.Resource // Load the image from an in-memory resource
  48. Image image.Image // Specify a loaded image to use in this canvas object
  49. Translucency float64 // Set a translucency value > 0.0 to fade the image
  50. FillMode ImageFill // Specify how the image should expand to fill or fit the available space
  51. ScaleMode ImageScale // Specify the type of scaling interpolation applied to the image
  52. }
  53. // Alpha is a convenience function that returns the alpha value for an image
  54. // based on its Translucency value. The result is 1.0 - Translucency.
  55. func (i *Image) Alpha() float64 {
  56. return 1.0 - i.Translucency
  57. }
  58. // Hide will set this image to not be visible
  59. func (i *Image) Hide() {
  60. i.baseObject.Hide()
  61. repaint(i)
  62. }
  63. // Move the image object to a new position, relative to its parent top, left corner.
  64. func (i *Image) Move(pos fyne.Position) {
  65. i.baseObject.Move(pos)
  66. repaint(i)
  67. }
  68. // Refresh causes this image to be redrawn with its configured state.
  69. func (i *Image) Refresh() {
  70. Refresh(i)
  71. }
  72. // Resize on an image will scale the content or reposition it according to FillMode.
  73. // It will normally cause a Refresh to ensure the pixels are recalculated.
  74. func (i *Image) Resize(s fyne.Size) {
  75. if s == i.Size() {
  76. return
  77. }
  78. if i.FillMode == ImageFillOriginal && i.size.Height > 2 { // don't refresh original scale images after first draw
  79. return
  80. }
  81. i.baseObject.Resize(s)
  82. Refresh(i)
  83. }
  84. // NewImageFromFile creates a new image from a local file.
  85. // Images returned from this method will scale to fit the canvas object.
  86. // The method for scaling can be set using the Fill field.
  87. func NewImageFromFile(file string) *Image {
  88. return &Image{
  89. File: file,
  90. }
  91. }
  92. // NewImageFromURI creates a new image from named resource.
  93. // File URIs will read the file path and other schemes will download the data into a resource.
  94. // HTTP and HTTPs URIs will use the GET method by default to request the resource.
  95. // Images returned from this method will scale to fit the canvas object.
  96. // The method for scaling can be set using the Fill field.
  97. //
  98. // Since: 2.0
  99. func NewImageFromURI(uri fyne.URI) *Image {
  100. if uri.Scheme() == "file" && len(uri.String()) > 7 {
  101. return &Image{
  102. File: uri.String()[7:],
  103. }
  104. }
  105. var read io.ReadCloser
  106. read, err := storage.Reader(uri) // attempt unknown / http file type
  107. if err != nil {
  108. fyne.LogError("Failed to open image URI", err)
  109. return &Image{}
  110. }
  111. defer read.Close()
  112. return NewImageFromReader(read, filepath.Base(uri.String()))
  113. }
  114. // NewImageFromReader creates a new image from a data stream.
  115. // The name parameter is required to uniquely identify this image (for caching etc.).
  116. // If the image in this io.Reader is an SVG, the name should end ".svg".
  117. // Images returned from this method will scale to fit the canvas object.
  118. // The method for scaling can be set using the Fill field.
  119. //
  120. // Since: 2.0
  121. func NewImageFromReader(read io.Reader, name string) *Image {
  122. data, err := ioutil.ReadAll(read)
  123. if err != nil {
  124. fyne.LogError("Unable to read image data", err)
  125. return nil
  126. }
  127. res := &fyne.StaticResource{
  128. StaticName: name,
  129. StaticContent: data,
  130. }
  131. return &Image{
  132. Resource: res,
  133. }
  134. }
  135. // NewImageFromResource creates a new image by loading the specified resource.
  136. // Images returned from this method will scale to fit the canvas object.
  137. // The method for scaling can be set using the Fill field.
  138. func NewImageFromResource(res fyne.Resource) *Image {
  139. return &Image{
  140. Resource: res,
  141. }
  142. }
  143. // NewImageFromImage returns a new Image instance that is rendered from the Go
  144. // image.Image passed in.
  145. // Images returned from this method will scale to fit the canvas object.
  146. // The method for scaling can be set using the Fill field.
  147. func NewImageFromImage(img image.Image) *Image {
  148. return &Image{
  149. Image: img,
  150. }
  151. }