Skip to content

JDSherbert/Juce-9-Slice-Image-Component

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image

Nine-Slice Image Component

Stars Badge

Forks Badge

Watchers Badge

Issues Badge


JUCE Component License




Overview

A JUCE Component that renders an image using nine-slice scaling (also known as scale-9 or border-image slicing). Nine-slice scaling divides an image into a 3×3 grid of regions (four corners, four edges, and a center) and scales each region independently. Corners are drawn at their original size, edges are stretched along one axis only, and the center fills the remaining space. This preserves crisp, undistorted corners regardless of how the component is resized, making it ideal for UI chrome such as panels, buttons, tooltips, and windows.


Features

  • Pixel-accurate nine-slice rendering via JUCE's Graphics::drawImage
  • Configurable per-side margins (left, top, right, bottom) via the Margin struct
  • Zero-size slice guard - empty source or destination rects are safely skipped
  • Configurable resampling quality (defaults to highResamplingQuality for modern UI assets). Worth noting you can change this to "low" for pixel or low res assets to sharpen them up.
  • Optional debug overlay that draws slice boundary lines and a component outline at runtime

Files

File Description
NineSliceImageComponent.h Component declaration, Margin, Slice, and SliceLayout structs
NineSliceImageComponent.cpp Layout construction and paint implementation

Integration

CMake (Recommended)

Add the following to your CMakeLists.txt. CMake will fetch the component directly from GitHub at configure time; no manual copying required!

cmakeinclude(FetchContent)

FetchContent_Declare(
    NineSliceImageComponent
    GIT_REPOSITORY https://github.com/JDSherbert/Juce-9-Slice-Image-Component.git
    GIT_TAG        main
    GIT_SHALLOW    TRUE
)

FetchContent_MakeAvailable(NineSliceImageComponent)

target_link_libraries(YourTarget
    PRIVATE
        NineSliceImageComponent
)

Then include the header in your source:

#include <NineSliceImageComponent.h>

Tip: Pin to a specific commit hash rather than main for reproducible builds:

GIT_TAG <commit-hash>

Manual

If you're not using CMake, copy NineSliceImageComponent.h and NineSliceImageComponent.cpp directly into your project and add them to your build system. No dependencies beyond JuceHeader.h are required.


Usage

Basic

Sherbert::NineSliceImageComponent nineSlice;

// Load your image however you like — BinaryData, File, ImageCache, etc.
juce::Image panelImage = juce::ImageCache::getFromMemory(BinaryData::panel_png, BinaryData::panel_pngSize);

// Define margins: how many pixels on each side are treated as fixed corners/edges.
// Here: 12px fixed regions on all sides.
Sherbert::Margin margin { 12, 12, 12, 12 };

nineSlice.setImage(panelImage, margin);
addAndMakeVisible(nineSlice);

Resizing

SliceLayout is rebuilt automatically on each paint call, so simply call setBounds() as normal; no manual layout invalidation required:

nineSlice.setBounds(getLocalBounds().reduced(20));

Resampling Quality

The default is highResamplingQuality, which produces smooth results for photographic source images. For pixel/low resolution art, you may prefer a lower setting to combat the anti-aliasing and keep it looking sharp:

nineSlice.setResamplingQuality(juce::Graphics::lowResamplingQuality);

Debug Overlay

Enable the debug overlay to visualise slice boundaries at runtime:

nineSlice.setShowDebugSlices(true);

This draws magenta lines at each slice boundary and a cyan outline around the component bounds.


API Reference

Margin

struct Margin
{
    int left   = 0;
    int top    = 0;
    int right  = 0;
    int bottom = 0;
};

Defines the fixed pixel thickness of each edge region. The corner size is the intersection of the adjacent edge thicknesses. For example, the top-left corner is left × top pixels.


NineSliceImageComponent

Method Description
setImage(image, margins) Sets the source image and slice margins. Triggers a repaint.
getMargins() Returns the current Margin by const reference.
setResamplingQuality(quality) Sets the juce::Graphics::ResamplingQuality used during paint.
setShowDebugSlices(bool) Toggles the debug slice boundary overlay.

How It Works

The SliceLayout constructor divides the source image and destination bounds into a 3×3 grid and pre-computes all nine { dst, src } rect pairs upfront. During paint(), each pair is passed directly to Graphics::drawImage, which handles the stretch. Because SliceLayout is rebuilt fresh on each paint call, it always reflects the current component bounds with no stale state.

Source image          Destination component
┌───┬───────┬───┐     ┌───┬─────────────┬───┐
│ TL│  Top  │TR │     │ TL│    Top      │TR │  ← corners: fixed size
├───┼───────┼───┤     ├───┼─────────────┼───┤
│   │       │   │     │   │             │   │
│ L │ Center│ R │     │ L │   Center    │ R │  ← edges: stretch on one axis
│   │       │   │     │   │             │   │  ← center: stretches on both axes
├───┼───────┼───┤     ├───┼─────────────┼───┤
│ BL│ Bottom│BR │     │ BL│   Bottom    │BR │  ← corners: fixed size
└───┴───────┴───┘     └───┴─────────────┴───┘

About

A JUCE component for rendering images with nine-slice (scale-9) scaling, preserving crisp corners at any size.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors