Skip to content

Conversation

@hkparker
Copy link
Contributor

@hkparker hkparker commented Aug 17, 2025

Description:

This PR adds basic camera support to the android device via a new CameraDevice interface. The CapturePhoto function launches an intent to open the camera app, and returns when the user is finished in the camera app. It returns an image, if an image was taken, and any errors.

I also standardized the java file on 4 space indent, since there was a mix of tabs and spaces in there, and 4 spaces seems to be the norm for java.

cameraDevice, ok := fyne.CurrentDevice().(sensor.CameraDevice)
if !ok {
	log.Error("camera is unsupported on this device")
	return
}

img, captured, err := cameraDevice.CapturePhoto()
if !captured {
	return
}
if err != nil {
	log.Error("error capturing photo: " + err.Error())
	return
}

// img is a valid image.Image from the device's camera

Requires fyne-io/tools#78 to build

Example App

Here's an example app to test with:

package main

import (
	"image/jpeg"
	"log"
	"os"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/driver/sensor"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/widget"
)

func main() {
	a := app.New()
	w := a.NewWindow("Camera")

	cameraDevice, isCameraDevice := fyne.CurrentDevice().(sensor.CameraDevice)

	resultImage := &canvas.Image{
		FillMode: canvas.ImageFillContain,
	}

	takePhoto := widget.NewButton("Take a photo!", func() {
		img, captured, err := cameraDevice.CapturePhoto()
		if !captured {
			return
		}
		if err != nil {
			dialog.ShowError(err, w)
			return
		}
		resultImage.Image = img
		resultImage.Refresh()
	})
	if !isCameraDevice {
		takePhoto.Disable()
	}

	w.SetContent(container.New(
		layout.NewBorderLayout(nil, takePhoto, nil, nil),
		takePhoto,
		container.NewStack(resultImage),
	))

	w.ShowAndRun()
}

Which looks this like:

camerademo.mp4

Unfortunately, the resolution of the resulting image is very small (192 × 255 pixels), which is a known issue when getting data back from MediaStore.ACTION_IMAGE_CAPTURE this way. It seems our only option for getting higher resolution images via the intent is to have the app write to a temp file we can open onActivityResult. See:

https://issuetracker.google.com/issues/36906325
https://medium.com/@appgeniuz08/capture-photo-via-intent-in-android-66749be91b9d
https://commonsware.com/blog/2015/06/08/action-image-capture-fallacy.html

Checklist:

  • Tests included.
  • Lint and formatter run with no errors.
  • Tests all pass.

Where applicable:

  • Public APIs match existing style and have Since: line.
  • Check for binary size increases when importing new modules.

@hkparker hkparker marked this pull request as draft August 17, 2025 13:18
@hkparker hkparker marked this pull request as ready for review August 17, 2025 18:53
@hkparker hkparker marked this pull request as draft August 19, 2025 11:52
@andydotxyz
Copy link
Member

andydotxyz commented Aug 21, 2025

It wires together great :) just FYI (not sure if this was expected) what I get is both low resolution and always seems to be landscape

@hkparker
Copy link
Contributor Author

hkparker commented Sep 6, 2025

I'm closing this out because there is no path to the ACTION_IMAGE_CAPTURE intent working for this feature. As I mentioned in slack, I do have a branch with camera-x support that works in the most basic way. I'd like to spend more time on that in order to support more of the camera-x features that would be required (like preview), and then discuss if there's a path to getting that merged in here.

@hkparker hkparker closed this Sep 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants