Skip to contents

Overview

This quickstart demonstrates the core workflow for computing artwork metrics from an image file. You’ll go from a Procreate export to benchmark-ready metrics in under 5 minutes.

Prerequisites

You need:

  1. An artwork image file (PNG or JPG from Procreate export)
  2. Artwork metadata from Procreate stats extraction:
    • File size in bytes
    • Drawing time in minutes
    • Brush stroke count

Basic Metric Computation

Example Data

Let’s use realistic example values:

# Artwork file path
img_path <- "~/artworks/landscape-sunset.png"

# Metadata from Procreate stats
file_sz <- 1847293        # ~1.8 MB file
draw_mins <- 145          # 2 hours 25 minutes
strokes <- 52340          # 52k brush strokes

Compute All Metrics

One function call computes everything:

metrics <- calc_art_metrics(
    img_path = img_path,
    file_sz = file_sz,
    draw_mins = draw_mins,
    strokes = strokes
)

# View results
print(metrics)

Output structure:

     metric_key        value
1: canvas_coverage   91.234567
2: n_unique_colors 9876.000000
3: share_of_spectrum  0.000589
...

Interpreting Metric Values

Understanding what the values mean helps validate results:

Canvas Coverage

metrics[metric_key == "canvas_coverage"]
#>          metric_key    value
#> 1: canvas_coverage 91.23457

# 91% = Artist used most of the canvas
# Low values (<50%) might indicate small artwork or lots of white space
# High values (>95%) suggest full canvas utilization

Color Palette Size

metrics[metric_key == "n_unique_colors"]
#>          metric_key value
#> 1: n_unique_colors  9876

# ~10k colors = Rich, detailed digital painting
# <1000 colors = Limited palette or simple illustration
# >20k colors = Complex artwork with extensive blending

Spectrum Coverage

metrics[metric_key == "share_of_spectrum"]
#>           metric_key      value
#> 1: share_of_spectrum 0.00058873

# 0.00059 = 0.059% of RGB color space
# Total RGB space = 16,777,216 colors (256^3)
# This artwork uses 9,876 / 16,777,216 = 0.059%
# Higher values indicate broader color exploration

Blending Quality

metrics[metric_key == "ave_blend_rate"]
#>        metric_key     value
#> 1: ave_blend_rate 0.8123456

# 0.81 = High blending rate (many colors created relative to strokes)
# Formula: 1 - (strokes / unique_colors)
# Higher values = more blending and color mixing
# Lower values = discrete strokes without much blending

Using Predictions

When Procreate stats aren’t available, estimate metrics from color count alone:

Extract Color Count from Image

# Get raster data
rast_data <- get_image_rast(img_path)

# Count unique colors
n_colors <- nrow(rast_data$colors)
print(n_colors)
#> [1] 9876

Predict Missing Metrics

# Predict brush strokes
strokes_pred <- predict_strokes(n_colors)
print(strokes_pred)
#>   n_unique_colors pred_strokes
#> 1            9876        53201

# Predict drawing time
minutes_pred <- predict_minutes(n_colors)
print(minutes_pred)
#>   n_unique_colors pred_minutes
#> 1            9876          142

Accuracy note: Predictions are estimates based on ML models. For our example with actual values:

  • Actual strokes: 52,340
  • Predicted strokes: 53,201
  • Error: ~1.6%

Good enough for benchmarking unverified artworks, but always prefer actual Procreate stats when available.

Preparing for Database Insert

Add identifiers to make metrics database-ready:

# Artwork and artist UUIDs from the upload process
metrics[, `:=`(
    art_uuid = "99a61148-1d3b-4340-8cf6-92ad26046b0f",
    artist_uuid = "746b8207-72f5-4ab6-8d19-a91d03daec3d",
    created_utc = Sys.time()
)]

# Now ready for insertion into artwork_stats table
# Usually handled by artutils::insert_artwork_metrics()

Quick Reference: Core Metrics

Metric Key Category What It Measures
canvas_coverage Time & Effort % of canvas with color
n_unique_colors Skill & Artistry Palette diversity
share_of_spectrum Skill & Artistry RGB color space utilization
ave_blend_rate Skill & Artistry Color blending quality
ave_colors_pstroke Complexity & Detail Colors per brush stroke
q75_color_freq Complexity & Detail Color frequency distribution

Common Pitfalls

Issue: All metrics return NA or error

Cause: Invalid image path or corrupt image file

Solution: Verify file exists and is readable by ImageMagick:

file.exists(img_path)
magick::image_read(img_path)

Issue: Canvas coverage = 0%

Cause: Image is all white/black or transparent

Solution: Check the artwork visually - may need different background filtering

Issue: Predictions way off from actual values

Cause: Artwork outside normal range (e.g., simple line art with high stroke count)

Solution: Predictions work best for typical digital paintings. Use actual stats when available.

Next Steps

For integration with platform benchmarking, see artutils::update_artist_benchmarks().