Skip to content
Client v5: BLE, BLE Hosting, HTTP, Jobs - Linux, MacOS, & Blazor Support! Full AOT, RX on BLE only & MANY other features! Power up!

MediaPickerButton

A button that lets the user add photos from the gallery and/or camera, compresses/re-encodes each to PNG or JPEG at a chosen quality (with optional max-dimension downscale), caps the count with MaxPhotos (added one at a time — the OS pickers are single-select), and shows the collected photos inline as a tappable carousel (opening the ImageViewer, with an optional Edit button that reuses the ImageEditor) or a compact pinch/zoom overlay. It ships inside the base packages — no extra dependency.

  • NuGet downloads for Shiny.Maui.Controls
  • NuGet downloads for Shiny.Blazor.Controls
Frameworks
.NET MAUI
Blazor

TODO: capture screenshots for media-picker-button.

<shiny:MediaPickerButton Photos="{Binding Photos}"
AllowGallery="True"
AllowCamera="True"
AllowPhotoEdit="True"
ShowAsCarouselInView="True"
MaxPhotos="5"
CompressionQuality="85"
OutputFormat="Jpeg"
PermissionDeniedText="Photo access was denied — enable it in Settings." />
[ObservableProperty]
ObservableCollection<MediaPickerItem> photos = new(); // Shiny.Maui.Controls.Media

OutputFormat is Shiny.Maui.Controls.ImageEditor.ImageExportFormat (Png / Jpeg).

<MediaPickerButton @bind-Photos="photos"
AllowGallery="true"
AllowCamera="true"
AllowPhotoEdit="true"
ShowAsCarouselInView="true"
MaxPhotos="5"
CompressionQuality="85"
OutputFormat="jpeg"
PermissionDeniedText="Photo access was denied." />
@code {
IReadOnlyList<Shiny.Blazor.Controls.MediaPickerItem> photos = [];
}

On Blazor OutputFormat is a string ("jpeg" / "png"), and each MediaPickerItem exposes a DataUri you can bind directly to <img src>.

PropertyTypeDefaultDescription
AllowGallerybooltrueOffer “choose from gallery”
AllowCamerabooltrueOffer “take photo”. When both are enabled, tapping shows a gallery/camera chooser
AllowPhotoEditboolfalseShow an Edit button in the viewer that opens the ImageEditor; edits are re-saved into the collection
PermissionDeniedTextstring”Permission denied…”Message shown when camera/gallery access is denied
NoImagesTemplateDataTemplate? / RenderFragment?nullShown when there are no photos yet (default: “No photos yet”)
ShowAsCarouselInViewbooltruetrue → inline thumbnail carousel; false → compact preview that opens a paged pinch/zoom overlay
MaxPhotosint1Maximum photos; the add trigger hides once reached
CompressionQualityint92Encoder quality as a percentage (1–100)
MaxImageDimensionint0If > 0, the longest edge is downscaled to this many pixels
OutputFormatImageExportFormat / stringJpeg / "jpeg"Output encoding — PNG or JPEG
PhotosIList / IReadOnlyList of MediaPickerItememptyThe collected photos (two-way)
AddButtonTextstring”➕ Add Photo”Text on the add trigger
GalleryActionText / CameraActionTextstring”Choose from Gallery” / “Take Photo”Chooser labels
UseFeedbackbool (MAUI)trueHaptic/sound feedback on actions
  • PhotoAdded / PhotoRemoved — a photo was added or removed (MediaPickerItem).
  • PhotosChanged (MAUI event + PhotosChangedCommand; Blazor EventCallback) — the collection changed.
  • PermissionDenied — camera/gallery access was denied (message string).
  • Multi-photo is add-one-at-a-time — each tap picks/captures a single photo and appends until MaxPhotos. The OS pickers do not offer native multi-select here.
  • MAUI is a plain ContentView using the built-in Microsoft.Maui.Media.MediaPicker — no handler or builder registration. The MediaPicker drives the OS permission prompts; a denial surfaces PermissionDeniedText.
  • Blazor self-imports its JS module (no DI). Gallery/camera use a hidden <input type="file" accept="image/*"> (with capture="environment" for the camera); compression/resize/format-conversion happen on an offscreen canvas.
  • Viewing reuses the ImageViewer (pinch/zoom); editing reuses the ImageEditor.
claude plugin marketplace add shinyorg/skills
claude plugin install controls@shiny
copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install controls@shiny
View controls Plugin