From e64975276de695e30e9b59a28d03c0ec6c865395 Mon Sep 17 00:00:00 2001 From: ErikKalkoken Date: Wed, 23 Oct 2024 16:57:13 +0200 Subject: [PATCH 1/2] Improve image docs --- canvas/image.md | 89 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/canvas/image.md b/canvas/image.md index d161755..21fa03b 100644 --- a/canvas/image.md +++ b/canvas/image.md @@ -7,15 +7,16 @@ redirect_from: A `canvas.Image` represents a scalable image resource in Fyne. It can be loaded from a resource (as shown in the example), from an -image file, from a URI location containing an image, from an `io.Reader`, or from a Go `image.Image` in memory. +image file, from a URI location containing an image, from an `io.Reader`, +or from a Go `image.Image` in memory. -The default image fill mode is `canvas.ImageFillStretch` which will -cause it to fill the space specified (through `Resize()` or layout). -Alternatively you could use `canvas.ImageFillContain` to ensure that -the aspect ratio is maintained and the image is within the bounds. -Further to this you can use `canvas.ImageFillOriginal` (as used -in the example here) which ensures that it will also have a minimum size -equal to that of the original image size. +Images can be bitmap based (like PNG and JPEG) or vector based +(such as SVG). Where possible we recommend scalable images as they will +continue to render well as sizes change. + +## Image from a resource + +The most common approach is to create a `canvas.Image` from a `fyne.Resource`. ```go package main @@ -30,21 +31,75 @@ func main() { myApp := app.New() w := myApp.NewWindow("Image") - image := canvas.NewImageFromResource(theme.FyneLogo()) - // image := canvas.NewImageFromURI(uri) - // image := canvas.NewImageFromImage(src) - // image := canvas.NewImageFromReader(reader, name) - // image := canvas.NewImageFromFile(fileName) - image.FillMode = canvas.ImageFillOriginal + r := theme.AccountIcon() + image := canvas.NewImageFromResource(r) + image.SetMinSize(fyne.Size{Width: 200, Height: 200}) w.SetContent(image) w.ShowAndRun() } ``` -Images can be bitmap based (like PNG and JPEG) or vector based -(such as SVG). Where possible we recommend scalable images as they will -continue to render well as sizes change. +In our example we use `theme.AccountIcon()`, because it is already available in the Fyne library. To use your own images you can bundle them into your project, which will make them available as Fyne resources. For more information please see [Bundling resources]({% link extend/bundle.md %}). + +## Image from a URL + +Images can also be created from URLs with `canvas.NewImageFromURI()`. This will fetch the image during runtime from a public image URL. + +Compared to the first example, an additional step is required to parse the URL into an URI: + +```go +package main + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/app" + "fyne.io/fyne/v2/canvas" + "fyne.io/fyne/v2/storage" +) + +func main() { + myApp := app.New() + w := myApp.NewWindow("Image") + + u, _ := storage.ParseURI("https://avatars.githubusercontent.com/u/36045855") + image := canvas.NewImageFromURI(u) + image.SetMinSize(fyne.Size{Width: 200, Height: 200}) + w.SetContent(image) + + w.ShowAndRun() +} +``` + +Please note that is it often better to bundle images with your Fyne app. Your image will be rendered faster and you avoid potential issues related to network access during runtime. + +## Image from other sources + +You can also create an image from other sources: + +- `image.Image`: `canvas.NewImageFromImage()` +- `io.Reader`: `canvas.NewImageFromReader()` +- file: `canvas.NewImageFromFile()` + +For more information please see the API documentation for `canvas.Image`. + +## Fillmode + +You can specify how the images should expand to fill or fit the available space with `Image.Fillmode`. + +The default fill mode is `canvas.ImageFillStretch` which will cause it +to fill the space specified (through `Resize()` or layout). + +Alternatively you could use `canvas.ImageFillContain` to ensure that +the aspect ratio is maintained and the image is within the bounds. + +When using `canvas.ImageFillStretch` or `canvas.ImageFillContain` you need to +specify a minimum size for your image with `Image.SetMinSize()`. +This ensures that your image is always rendered with the same size on different platforms and screen sizes. + +Another available fill mode is `canvas.ImageFillOriginal`. +This mode ensures that the image will have a minimum size equal to that of the original image size +and therefore does not require you to set a minimum size. Be careful when using original image sizes as they may not behave exactly as expected with different user interface scales. As Fyne allows the entire user interface to scale, a 25px image file From 97539d27daeab4ab755530f778dd3efc19af22aa Mon Sep 17 00:00:00 2001 From: ErikKalkoken Date: Mon, 28 Oct 2024 17:30:28 +0100 Subject: [PATCH 2/2] Correct image text with respect to minimum size --- canvas/image.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/canvas/image.md b/canvas/image.md index 21fa03b..9e3614c 100644 --- a/canvas/image.md +++ b/canvas/image.md @@ -22,6 +22,7 @@ The most common approach is to create a `canvas.Image` from a `fyne.Resource`. package main import ( + "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/theme" @@ -33,15 +34,16 @@ func main() { r := theme.AccountIcon() image := canvas.NewImageFromResource(r) - image.SetMinSize(fyne.Size{Width: 200, Height: 200}) w.SetContent(image) - + w.Resize(fyne.NewSize(200, 200)) w.ShowAndRun() } ``` In our example we use `theme.AccountIcon()`, because it is already available in the Fyne library. To use your own images you can bundle them into your project, which will make them available as Fyne resources. For more information please see [Bundling resources]({% link extend/bundle.md %}). +Please note that we are setting a size for the window. This is necessary, because images normally do not have a minimum size and Fyne would draw a window with zero width and height. For more details please see the section about [Fillmode](#fillmode). + ## Image from a URL Images can also be created from URLs with `canvas.NewImageFromURI()`. This will fetch the image during runtime from a public image URL. @@ -64,9 +66,8 @@ func main() { u, _ := storage.ParseURI("https://avatars.githubusercontent.com/u/36045855") image := canvas.NewImageFromURI(u) - image.SetMinSize(fyne.Size{Width: 200, Height: 200}) w.SetContent(image) - + w.Resize(fyne.NewSize(200, 200)) w.ShowAndRun() } ``` @@ -93,13 +94,17 @@ to fill the space specified (through `Resize()` or layout). Alternatively you could use `canvas.ImageFillContain` to ensure that the aspect ratio is maintained and the image is within the bounds. -When using `canvas.ImageFillStretch` or `canvas.ImageFillContain` you need to -specify a minimum size for your image with `Image.SetMinSize()`. -This ensures that your image is always rendered with the same size on different platforms and screen sizes. +Please note that with `canvas.ImageFillStretch` and `canvas.ImageFillContain` images +will use the available space of their container, but do not have a minimum size. +This means that layouts that shrink their objects to their minimum size +(e.g. `layout.NewHBoxLayout()`) will shrink images to zero. +In those cases you can set a minimum size yourself with `Image.SetMinSize()`. Another available fill mode is `canvas.ImageFillOriginal`. -This mode ensures that the image will have a minimum size equal to that of the original image size -and therefore does not require you to set a minimum size. +It ensures that the container grows to the pixel dimensions required to fit the original image. +The aspect of the image will be maintained so, +as with ImageFillContain there may be transparent areas around the image. + Be careful when using original image sizes as they may not behave exactly as expected with different user interface scales. As Fyne allows the entire user interface to scale, a 25px image file