Pica.Viewer
1.2.2-preview.1
dotnet add package Pica.Viewer --version 1.2.2-preview.1
NuGet\Install-Package Pica.Viewer -Version 1.2.2-preview.1
<PackageReference Include="Pica.Viewer" Version="1.2.2-preview.1" />
<PackageVersion Include="Pica.Viewer" Version="1.2.2-preview.1" />
<PackageReference Include="Pica.Viewer" />
paket add Pica.Viewer --version 1.2.2-preview.1
#r "nuget: Pica.Viewer, 1.2.2-preview.1"
#:package Pica.Viewer@1.2.2-preview.1
#addin nuget:?package=Pica.Viewer&version=1.2.2-preview.1&prerelease
#tool nuget:?package=Pica.Viewer&version=1.2.2-preview.1&prerelease
English | Русский
<img src="src/Pica.Viewer/Assets/AppIcon.ico" alt="Pica" width="32" height="32"> Pica
A convenient image viewer. It can run as a standalone application or be used by other applications as an embedded viewer.
Main features
- Viewing images, animations, and multi-page formats.
- Animation mini-player with seeking support.
- Viewing individual channels with the same functionality as regular images.
- Area selection (pixels are taken directly from the image without any modifications).
- Automatic fitting of the window size to the image.
- Pinning the window on top of other windows.
- Customizable display of information, such as the name, format, resolution, or modification date.
- Useful context menu items, including a proper "Open with" menu.
- Full support for formats:
.png,.jpeg,.webp,.bmp,.gif,.ico,.cur,.avif,.heic,.heif,.tif.
Controls
| Action | Hotkeys |
|---|---|
| Previous image or channel | A or ← |
| Next image or channel | D or → |
| Previous image or animation within the current file | Shift, Ctrl, or Alt + A or ← |
| Next image or animation within the current file | Shift, Ctrl, or Alt + D or → |
| Previous animation frame | , |
| Next animation frame | . |
| Zoom | Mouse wheel |
| Slow zoom | Hold Shift, Ctrl, or Alt while zooming |
| Pan | Drag with LMB or MMB |
| Slow pan | Hold Shift or Alt while panning |
| Reset zoom and position | Space |
| Channel mode | Tab |
| Transparency background | T |
| Image filtering | F |
| Copy | Ctrl + C |
| Select area | Ctrl + drag with LMB |
| Select the entire image | Ctrl + A |
| Pan the image while an area selection is active | Drag with MMB |
| Switch between windowed and fullscreen modes | Double-click with LMB, if enabled in the settings |
| Close window or cancel | Esc |
Quick start
Installation
Add the package:
dotnet add package Pica.Viewer
For a prerelease version, use --prerelease or specify the version number explicitly.
Theme
If the application does not yet use Fluent and SukiUI, add them to App.axaml:
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:suki="using:SukiUI"
x:Class="Example.Desktop.App">
<Application.Styles>
<FluentTheme />
<suki:SukiTheme ThemeColor="Blue" />
</Application.Styles>
</Application>
Example
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Pica.Protocol;
using Pica.Viewer;
using Pica.Viewer.Services;
using Pica.Viewer.Views;
ServiceCollection services = new();
services.AddLogging(builder =>
{
builder.SetMinimumLevel(LogLevel.Warning);
});
services.AddPicaViewer();
ServiceProvider serviceProvider = services.BuildServiceProvider();
Guid imageId = Guid.NewGuid();
string imagePath = Path.GetFullPath("image.png");
string imageName = Path.GetFileName(imagePath);
PicaImageItem image = new(imageId, imagePath, imageName);
PicaViewerRequest request = new([image], imageId);
IImageViewerWindowFactory windowFactory = serviceProvider.GetRequiredService<IImageViewerWindowFactory>();
ImageViewerWindow window = await windowFactory.CreateAsync(request, CancellationToken.None);
window.Show();
window.Show() must be called on the UI thread.
Pica forwards logs to the logging system already configured by the application and does not modify it.
Multiple images
Pass all images in PicaViewerRequest.Items, and the ID of the initially selected image in SelectedItemId:
PicaViewerRequest request = new(images, selectedImageId);
You can pass the path to a ready-made low-resolution image in PicaImageItem.PreviewFilePath for fast loading. If there is no preview image, this parameter can be omitted, but loading may take slightly longer.
In-memory images
To show an Avalonia Bitmap without first writing it to disk, associate the image ID with an IPicaImageBitmapSource and pass the sources to CreateAsync:
IReadOnlyDictionary<Guid, IPicaImageBitmapSource> bitmapSources =
new Dictionary<Guid, IPicaImageBitmapSource>
{
[imageId] = new MyBitmapSource(bitmap)
};
IViewerActionDispatcher actionDispatcher = new ViewerActionDispatcher();
ImageViewerWindow window = await windowFactory.CreateAsync(
request,
actionDispatcher,
bitmapSources,
CancellationToken.None);
AcquireAsync must return an IPicaImageBitmapLease. Pica keeps the lease while it uses the bitmap and disposes it when the bitmap is no longer needed. Set IsFileBacked to false for a memory-only image: Pica then uses PicaImageItem.FileName when saving or creating a temporary PNG for "Open with", and does not read file metadata from FilePath. Set it to true only when FilePath points to the original image file.
Custom context menu items
Pass the list of items in PicaViewerRequest and their click handler in CreateAsync:
PicaActionDefinition[] actions =
[
new(
Id: "open-in-editor",
DisplayName: "Open in editor",
IconGeometry: "M13,3 L20,3 L20,10 L18,10 L18,6.4 L9.4,15 L8,13.6 L16.6,5 L13,5 Z M4,5 L10,5 L10,7 L6,7 L6,17 L16,17 L16,13 L18,13 L18,19 L4,19 Z",
IconRotationDegrees: 0d,
Targets: PicaActionTargets.CurrentImage | PicaActionTargets.Selection,
Order: 0)
{
SelectionPlacement = PicaSelectionActionPlacement.AfterSave
}
];
PicaViewerRequest request = new(images, selectedImageId, actions);
ImageViewerWindow window = await windowFactory.CreateAsync(request, actionDispatcher, CancellationToken.None);
actions is a list of PicaActionDefinition, and actionDispatcher is an implementation of IViewerActionDispatcher.
Pica calls DispatchCurrentImageAsync for the original image, DispatchSelectionAsync for the selected fragment, and DispatchDerivedImageAsync for the selected channel.
Example implementation of IViewerActionDispatcher:
public class ViewerActionDispatcher : IViewerActionDispatcher
{
public Task DispatchCurrentImageAsync(
PicaActionDefinition action,
PicaImageItem item,
CancellationToken ct)
{
return MyImageEditor.OpenAsync(item.FilePath, ct);
}
public Task DispatchSelectionAsync(
PicaActionDefinition action,
PicaImageItem item,
byte[] pngContent,
CancellationToken ct)
{
return MyImageEditor.OpenAsync(PicaImageFormats.SelectionFileName, pngContent, ct);
}
public Task DispatchDerivedImageAsync(
PicaActionDefinition action,
PicaImageItem item,
string fileName,
byte[] pngContent,
CancellationToken ct)
{
return MyImageEditor.OpenAsync(fileName, pngContent, ct);
}
}
MyImageEditor in the example is an application class that opens an image by path or from a byte array.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- AnimatedImage (>= 2.1.4)
- Avalonia (>= 12.0.5)
- Avalonia.Desktop (>= 12.0.5)
- CommunityToolkit.Mvvm (>= 8.4.2)
- Magick.NET-Q8-AnyCPU (>= 14.15.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Pica.Protocol (>= 1.2.2-preview.1)
- SkiaSharp (>= 3.119.4)
- SukiUI (>= 7.0.2-nightly20260625)
- System.Drawing.Common (>= 10.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.2-preview.1 | 41 | 9/15/2026 |
| 1.2.1-preview.1 | 59 | 9/8/2026 |
| 1.2.0-preview.1 | 88 | 8/12/2026 |
| 1.1.1-preview.1 | 66 | 7/30/2026 |
| 1.1.0-preview.1 | 63 | 7/29/2026 |
| 1.0.3-preview.1 | 63 | 7/27/2026 |
| 1.0.2-preview.1 | 66 | 7/27/2026 |
| 1.0.1-preview.1 | 62 | 7/27/2026 |
| 1.0.0-preview.1 | 82 | 7/27/2026 |