Files
HawkeyeVision/Hawkeye.VisionBuilder/Features/ImagesStrip/Components/ImageThumbnailControl.cs

151 lines
4.5 KiB
C#

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace Hawkeye.VisionBuilder.Features.ImagesStrip.Components
{
/// <summary>
/// Represents a single image thumbnail item with an image and filename label.
/// </summary>
public class ImageThumbnailControl : Panel
{
private const int ThumbnailSize = 108;
private const int BorderWidth = 3;
private readonly PictureBox _pictureBox;
private readonly Label _label;
private bool _isSelected;
private string _imagePath;
public string ImagePath
{
get => _imagePath;
set
{
_imagePath = value;
LoadImage(value);
_label.Text = Path.GetFileNameWithoutExtension(value);
}
}
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected != value)
{
_isSelected = value;
Invalidate(); // Trigger repaint to show/hide border
}
}
}
public event EventHandler ThumbnailClicked;
public ImageThumbnailControl()
{
// Set up the container panel
Width = ThumbnailSize + (BorderWidth * 2);
Height = ThumbnailSize + 25 + (BorderWidth * 2); // Extra space for label
Margin = new Padding(5);
Cursor = Cursors.Hand;
// Create PictureBox for the image
_pictureBox = new PictureBox
{
Width = ThumbnailSize,
Height = ThumbnailSize,
SizeMode = PictureBoxSizeMode.StretchImage,
Location = new System.Drawing.Point(BorderWidth, BorderWidth),
BackColor = Color.Black
};
_pictureBox.Click += OnThumbnailClick;
// Create Label for the filename
_label = new Label
{
Width = ThumbnailSize,
Height = 20,
Location = new System.Drawing.Point(BorderWidth, ThumbnailSize + BorderWidth + 2),
TextAlign = ContentAlignment.MiddleCenter,
AutoEllipsis = true,
Font = new Font("Segoe UI", 8f)
};
_label.Click += OnThumbnailClick;
Controls.Add(_pictureBox);
Controls.Add(_label);
// Enable double buffering to reduce flicker
DoubleBuffered = true;
}
private void LoadImage(string imagePath)
{
try
{
if (File.Exists(imagePath))
{
using (var mat = new Mat(imagePath))
{
var resized = mat.Resize(new OpenCvSharp.Size(ThumbnailSize, ThumbnailSize));
var bitmap = resized.ToBitmap();
// Dispose old image if exists
var oldImage = _pictureBox.Image;
_pictureBox.Image = bitmap;
oldImage?.Dispose();
}
}
}
catch (Exception ex)
{
// If image loading fails, show error in label
_label.Text = "Error loading image";
_label.ForeColor = Color.Red;
}
}
private void OnThumbnailClick(object sender, EventArgs e)
{
ThumbnailClicked?.Invoke(this, EventArgs.Empty);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Draw selection border if selected
if (_isSelected)
{
using (var pen = new Pen(Color.DodgerBlue, BorderWidth))
{
var rect = new Rectangle(
BorderWidth / 2,
BorderWidth / 2,
Width - BorderWidth,
Height - BorderWidth
);
e.Graphics.DrawRectangle(pen, rect);
}
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
// Dispose the image to free memory
_pictureBox?.Image?.Dispose();
_pictureBox?.Dispose();
_label?.Dispose();
}
base.Dispose(disposing);
}
}
}