BeepImage
Advanced image control with SVG support, animations, transformations, and clipping
📑 Table of Contents
Overview
BeepImage is a powerful image control that supports multiple image formats including SVG, PNG, JPG, and BMP. It provides advanced features like animations, transformations, image clipping shapes, theme integration, and both embedded resource and file system loading capabilities.
Built on top of the BeepControl base class, BeepImage inherits all the theming and styling
capabilities while adding image-specific features like rotation, flipping, scaling modes, and visual effects.
Key Features
🖼️ SVG Support
Native SVG rendering with theme-aware coloring and dynamic styling
🎬 Animations
Built-in spinning, pulsing, bouncing, fading, and shaking animations
🔄 Transformations
Rotation, flipping, and scaling with multiple scale modes
✂️ Clipping Shapes
Circle, rounded rectangle, ellipse, diamond, triangle, and hexagon clipping
📦 Resource Loading
Load from embedded resources or file system automatically
✨ Visual Effects
Grayscale, opacity, and custom color filtering
📐 Smart Scaling
Multiple scaling modes with aspect ratio preservation
🎨 Theme Integration
Automatic theme color application to SVG elements
Basic Usage
Simple Image Display
// Create a basic BeepImage
var image = new BeepImage
{
ImagePath = "icons/user.svg",
Size = new Size(64, 64),
Location = new Point(10, 10),
ScaleMode = ImageScaleMode.KeepAspectRatio
};
// Add to form
this.Controls.Add(image);
Themed SVG Image
var themedIcon = new BeepImage
{
ImagePath = "icons/settings.svg",
ApplyThemeOnImage = true,
Size = new Size(32, 32),
ImageEmbededin = ImageEmbededin.Button
};
Animated Spinning Image
var spinner = new BeepImage
{
ImagePath = "icons/loading.svg",
IsSpinning = true,
SpinSpeed = 5f,
Size = new Size(48, 48)
};
BeepImage automatically detects whether the ImagePath is an embedded resource or file system path and loads accordingly.
Properties
Image Properties
| Property | Type | Description |
|---|---|---|
ImagePath |
string | Path to image file (SVG, PNG, JPG, BMP) or embedded resource |
Image |
Image | Direct image object assignment |
BaseSize |
int | Default size before scaling |
ScaleMode |
ImageScaleMode | How image should be scaled within bounds |
ScaleFactor |
float | Manual scaling factor |
HasImage |
bool (readonly) | Indicates if an image is loaded |
Animation Properties
IsSpinning bool
Enable continuous spinning animation
SpinSpeed float
Speed of spinning in degrees per frame
IsPulsing bool
Enable pulsing scale animation
IsBouncing bool
Enable bouncing scale animation
IsFading bool
Enable fading opacity animation
IsShaking bool
Enable horizontal shaking animation
Transformation Properties
| Property | Type | Description |
|---|---|---|
ManualRotationAngle |
float | Manual rotation angle in degrees |
AllowManualRotation |
bool | Whether manual rotation is allowed |
Velocity |
float | Rotation velocity for physics-based rotation |
Clipping Properties
| Property | Type | Values | Description |
|---|---|---|---|
ClipShape |
ImageClipShape | None, Circle, RoundedRect, Ellipse, Diamond, Triangle, Hexagon, Custom | Shape used to clip the image |
CornerRadius |
float | - | Corner radius for RoundedRect shape |
CustomClipPath |
GraphicsPath | - | Custom clipping path for advanced shapes |
Effects & Theme Properties
Grayscale bool
Convert image to grayscale
Opacity float
Image opacity (0.0 to 1.0)
ApplyThemeOnImage bool
Apply theme colors to SVG images
FillColor / StrokeColor Color
Fill and stroke colors for SVG elements
Methods
Image Management
| Method | Parameters | Description |
|---|---|---|
LoadImage |
string path | Load image from file or embedded resource |
ClearImage |
none | Clear current image and free resources |
GetImageSize |
none | Get original size of loaded image |
GenerateShapedImage |
Image sourceImage | Generate image with current clipping shape applied |
Transformations
Rotate90Clockwise()
Rotate image 90 degrees clockwise
Rotate90CounterClockwise()
Rotate image 90 degrees counter-clockwise
Rotate180()
Rotate image 180 degrees
FlipHorizontal() / FlipVertical()
Flip image horizontally or vertically
ResetTransformations()
Reset all rotations and flips to default
SVG Theming
| Method | Parameters | Description |
|---|---|---|
ApplyThemeToSvg |
none | Apply current theme colors to SVG elements |
ApplyColorToAllElements |
Color fillColor | Apply specific color to all SVG elements |
Events
| Event | Type | Description |
|---|---|---|
Click |
EventHandler | Triggered when image is clicked |
MouseEnter |
EventHandler | Triggered when mouse enters image area |
MouseLeave |
EventHandler | Triggered when mouse leaves image area |
DoubleClick |
EventHandler | Triggered on double-click for detailed actions |
Event Handling Examples
var image = new BeepImage
{
ImagePath = "icons/photo.svg",
ClipShape = ImageClipShape.Circle
};
// Handle click for image preview
image.Click += (s, e) => {
ShowImagePreview(image.ImagePath);
};
// Add hover effects (if not IsStillImage)
image.MouseEnter += (s, e) => {
image.IsPulsing = true;
};
image.MouseLeave += (s, e) => {
image.IsPulsing = false;
};
// Handle double-click for rotation
image.DoubleClick += (s, e) => {
image.Rotate90Clockwise();
};
Examples
Circular Profile Picture
public BeepImage CreateProfilePicture(string imagePath)
{
var profilePic = new BeepImage
{
ImagePath = imagePath,
Size = new Size(100, 100),
ClipShape = ImageClipShape.Circle,
ScaleMode = ImageScaleMode.Stretch,
Cursor = Cursors.Hand
};
profilePic.Click += (s, e) => {
OpenProfileEditor();
};
// Add hover effect
profilePic.MouseEnter += (s, e) => {
profilePic.IsPulsing = true;
};
profilePic.MouseLeave += (s, e) => {
profilePic.IsPulsing = false;
};
return profilePic;
}
Animated Loading Spinner
public class LoadingSpinner : BeepImage
{
public LoadingSpinner()
{
ImagePath = "icons/spinner.svg";
Size = new Size(40, 40);
SpinSpeed = 8f;
ApplyThemeOnImage = true;
ImageEmbededin = ImageEmbededin.Form;
Visible = false; // Hidden by default
}
public void StartLoading()
{
IsSpinning = true;
Visible = true;
}
public void StopLoading()
{
IsSpinning = false;
Visible = false;
}
}
// Usage
var loadingSpinner = new LoadingSpinner
{
Location = new Point(200, 200)
};
this.Controls.Add(loadingSpinner);
// Start/stop based on loading state
async void LoadDataAsync()
{
loadingSpinner.StartLoading();
try
{
await SimulateDataLoading();
}
finally
{
loadingSpinner.StopLoading();
}
}
Icon Button with Effects
public BeepImage CreateIconButton(string iconPath, Color hoverColor, Action clickAction)
{
var iconButton = new BeepImage
{
ImagePath = iconPath,
Size = new Size(24, 24),
ApplyThemeOnImage = true,
ClipShape = ImageClipShape.RoundedRect,
CornerRadius = 4f,
Cursor = Cursors.Hand
};
Color originalColor = iconButton.FillColor;
// Add hover effects
iconButton.MouseEnter += (s, e) => {
iconButton.IsPulsing = true;
iconButton.ApplyColorToAllElements(hoverColor);
};
iconButton.MouseLeave += (s, e) => {
iconButton.IsPulsing = false;
iconButton.ApplyThemeToSvg(); // Restore theme colors
};
iconButton.Click += (s, e) => {
clickAction?.Invoke();
};
return iconButton;
}
// Usage
var deleteButton = CreateIconButton("icons/delete.svg", Color.Red, () => {
if (MessageBox.Show("Delete item?", "Confirm",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
DeleteItem();
}
});
Image Gallery with Transformations
public class ImageGallery : UserControl
{
private FlowLayoutPanel galleryPanel;
public ImageGallery()
{
InitializeGallery();
}
private void InitializeGallery()
{
galleryPanel = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
AutoScroll = true,
FlowDirection = FlowDirection.LeftToRight,
WrapContents = true
};
this.Controls.Add(galleryPanel);
}
public void AddImage(string imagePath)
{
var galleryImage = new BeepImage
{
ImagePath = imagePath,
Size = new Size(150, 150),
ClipShape = ImageClipShape.RoundedRect,
CornerRadius = 8f,
ScaleMode = ImageScaleMode.KeepAspectRatio,
Cursor = Cursors.Hand,
Margin = new Padding(5)
};
// Add context menu for transformations
var contextMenu = new ContextMenuStrip();
contextMenu.Items.Add("Rotate 90°", null, (s, e) => galleryImage.Rotate90Clockwise());
contextMenu.Items.Add("Rotate -90°", null, (s, e) => galleryImage.Rotate90CounterClockwise());
contextMenu.Items.Add("Flip Horizontal", null, (s, e) => galleryImage.FlipHorizontal());
contextMenu.Items.Add("Flip Vertical", null, (s, e) => galleryImage.FlipVertical());
contextMenu.Items.Add("Reset", null, (s, e) => galleryImage.ResetTransformations());
contextMenu.Items.Add(new ToolStripSeparator());
contextMenu.Items.Add("Remove", null, (s, e) => {
galleryPanel.Controls.Remove(galleryImage);
galleryImage.Dispose();
});
galleryImage.ContextMenuStrip = contextMenu;
// Add click handler for full view
galleryImage.Click += (s, e) => {
ShowImageFullScreen(imagePath);
};
galleryPanel.Controls.Add(galleryImage);
}
private void ShowImageFullScreen(string imagePath)
{
// Implementation for full-screen image viewer
var fullScreenForm = new Form
{
WindowState = FormWindowState.Maximized,
FormBorderStyle = FormBorderStyle.None,
BackColor = Color.Black
};
var fullImage = new BeepImage
{
ImagePath = imagePath,
Dock = DockStyle.Fill,
ScaleMode = ImageScaleMode.KeepAspectRatio
};
fullImage.Click += (s, e) => fullScreenForm.Close();
fullScreenForm.Controls.Add(fullImage);
fullScreenForm.Show();
}
}
Notification Badge Image
public class NotificationIcon : BeepImage
{
private int notificationCount;
private Timer bounceTimer;
public NotificationIcon()
{
ImagePath = "icons/notification.svg";
Size = new Size(32, 32);
ApplyThemeOnImage = true;
bounceTimer = new Timer { Interval = 2000 };
bounceTimer.Tick += (s, e) => {
IsBouncing = false;
bounceTimer.Stop();
};
}
public int NotificationCount
{
get => notificationCount;
set
{
var oldCount = notificationCount;
notificationCount = value;
if (value > oldCount)
{
ShowNewNotificationAnimation();
}
// Update badge text or visibility
UpdateBadgeDisplay();
}
}
private void ShowNewNotificationAnimation()
{
IsBouncing = true;
bounceTimer.Stop();
bounceTimer.Start();
}
private void UpdateBadgeDisplay()
{
// Update badge text or additional overlay
// This could be implemented with a separate control overlay
this.Invalidate(); // Trigger repaint for badge
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
bounceTimer?.Dispose();
}
base.Dispose(disposing);
}
}
// Usage
var notificationIcon = new NotificationIcon
{
Location = new Point(20, 20)
};
this.Controls.Add(notificationIcon);
// Simulate new notifications
notificationIcon.NotificationCount = 3; // Will trigger bounce animation
Theming
BeepImage supports sophisticated theming, especially for SVG images:
Automatic Theme Application
var themedIcon = new BeepImage
{
ImagePath = "icons/settings.svg",
ApplyThemeOnImage = true,
ImageEmbededin = ImageEmbededin.MenuBar
};
// Theme colors will be applied based on context:
// - MenuBar context uses MenuForeColor/MenuBackColor
// - Button context uses ButtonForeColor/ButtonBackColor
// - Form context uses general foreground/background colors
Context-Specific Theming
- ImageEmbededin.Button - Uses button theme colors
- ImageEmbededin.MenuBar - Uses menu theme colors
- ImageEmbededin.Form - Uses form/general theme colors
- ImageEmbededin.Header - Uses header theme colors
Manual Color Application
// Apply specific colors to SVG
var coloredIcon = new BeepImage
{
ImagePath = "icons/star.svg"
};
// Apply custom color to all SVG elements
coloredIcon.ApplyColorToAllElements(Color.Gold);
// Or set individual colors
coloredIcon.FillColor = Color.Gold;
coloredIcon.StrokeColor = Color.DarkGoldenrod;
// Apply the colors
coloredIcon.ApplyThemeToSvg();
Preserve Background Colors
var complexIcon = new BeepImage
{
ImagePath = "icons/multi-color.svg",
ApplyThemeOnImage = true,
PreserveSvgBackgrounds = true // Keep original background colors
};
Use the ImageEmbededin property to get contextually appropriate theme colors for different UI areas.
Best Practices
⚡ Performance Guidelines
- Image optimization: Use appropriately sized images for better performance
- Animation usage: Disable animations when not visible to save CPU
- Resource management: Call
ClearImage()when disposing to free memory - SVG complexity: Keep SVG files simple for better rendering performance
- Animation limits: Avoid too many simultaneous animations
🎨 Design Guidelines
- Consistent sizing: Use consistent image sizes within related UI elements
- Clipping shapes: Use clipping shapes consistently throughout your application
- Animation purpose: Use animations purposefully, not decoratively
- Theme integration: Always use
ApplyThemeOnImagefor system icons - Visual hierarchy: Use different sizes and effects to establish importance
♿ Accessibility
- Alternative text: Provide tooltips for images that convey information
- Color independence: Don't rely solely on color changes for state indication
- Animation sensitivity: Consider providing options to disable animations
- High contrast: Ensure images work well in high contrast themes
- Screen readers: Use proper accessibility attributes
🔧 Technical Considerations
- Embedded resources: Use embedded resources for shipped icons and graphics
- File system: Use file system loading for user-provided images
- Error handling: Always handle image loading failures gracefully
- Memory management: Dispose of images properly to prevent memory leaks
- Thread safety: Ensure image loading happens on appropriate threads
Animations are automatically disabled in design mode. Test animations at runtime to ensure they work as expected.
BeepImage automatically detects embedded resources vs. file paths and loads accordingly, making it easy to switch between development and production scenarios.