PRD – Kotlin Notebook Image Rendering for Computer Vision
1. Overview
Goal:
Provide a simple, Kotlin-native, notebook-friendly way to render images inline inside Kotlin notebooks for computer vision workflows, comparable in ease of use to Python’s PIL.Image.show() or display().
Target users:
- Kotlin Notebook users
- Computer vision engineers / researchers
- sk-ai-net / skainet-notebook community
Leverages Kotlin Notebook rich output APIs:
https://kotlinlang.org/docs/data-analysis-notebooks-output-formats.html#rich-text
2. Problem Statement
Kotlin notebooks currently lack a clean, idiomatic way to show images inline. Typical approaches:
| Approach |
Issues |
Swing/AWT (JFrame) |
Breaks notebook flow, not inline |
| Save to file + link |
Slow, inconvenient |
| Manual HTML + base64 |
Verbose and error-prone |
| Java interop hacks |
Not idiomatic Kotlin |
2.1 Reference: Python PIL API
In Python notebooks the workflow is extremely concise and expressive:
from PIL import Image
from IPython.display import display
img = Image.open("sample.jpg")
display(img)
# or even simpler
img
Key qualities to match:
- One-line image display
- Inline notebook rendering
- Automatic type recognition
- No explicit HTML or GUI code
- Natural REPL/notebook flow
The Kotlin solution must aim to replicate this experience from a developer ergonomics standpoint.
3. Objectives
Deliver a small utility module that:
- Displays images inline in Kotlin notebooks
- Feels idiomatic to Kotlin users
- Matches Python PIL display ergonomics as closely as possible
- Supports multiple input sources
- Uses native notebook rich HTML output
- Avoids Swing GUIs or window popups
4. User Stories
US-01 – Display from BufferedImage
US-02 – Display from file path
display("assets/sample.jpg")
US-03 – Display from ByteArray
US-04 – Display with sizing options
display(img) {
width = 256
height = 256
}
US-05 – Multi-image display
display(listOf(img1, img2, img3))
5. Functional Requirements
Supported Inputs
| Source |
Type |
| Loaded images |
BufferedImage |
| Encoded image data |
ByteArray |
| Filesystem paths |
String, Path |
| Remote sources |
URL |
Output Rendering
- Render using
<img> HTML tags
- Inline base64 sources (
data:image/*;base64)
- Emitted via Kotlin Notebook rich output (
HTML(...))
Styling Controls
Optional DSL settings:
width, height
alt text
border toggle
cssClass
Batch / Grid Mode
Lists render as responsive image rows or grids.
6. Non-Functional Requirements
| Category |
Requirement |
| Performance |
<50ms encode + render per image |
| Platform |
JVM 11+ |
| Notebook |
Compatible with skainet-notebook & IntelliJ Kotlin Notebooks |
| Dependencies |
No GUI frameworks required |
| Accessibility |
Support alt text |
7. API Design
Core function
display(image: Any, options: DisplayOptions.() -> Unit = {})
Overloads
display(img: BufferedImage)
display(bytes: ByteArray)
display(path: String)
display(url: URL)
display(images: List<BufferedImage>)
Options DSL
class DisplayOptions {
var width: Int? = null
var height: Int? = null
var alt: String = ""
var border: Boolean = false
var cssClass: String? = null
}
8. Implementation Strategy
Rendering model
<img src="data:image/png;base64,{base64}" />
Injected via:
HTML(htmlString).display()
Conversion utilities
fun BufferedImage.toBase64(): String
fun bytesToImage(bytes: ByteArray): BufferedImage
Dispatcher
fun display(obj: Any, options: DisplayOptions.() -> Unit = {}) {
when (obj) {
is BufferedImage -> render(obj, options)
is ByteArray -> render(bytesToImage(obj), options)
is String -> render(ImageIO.read(File(obj)), options)
is URL -> render(ImageIO.read(obj), options)
is List<*> -> renderGrid(obj.filterIsInstance<BufferedImage>())
else -> error("Unsupported image source")
}
}
Grid HTML layout
<div style="display:flex; gap:8px;">
<img ... />
<img ... />
<img ... />
</div>
9. Example Notebook Usage
import skai.display.*
val img = ImageIO.read(File("sample.jpg"))
display(img)
display(img) {
width = 256
height = 256
border = true
}
display(listOf(img, img, img))
10. Developer Experience
- One-line image display
- Python-PIL-style ergonomics
- No pop-ups or windows
- No file roundtrips
- Pure inline notebook output
11. skainet-notebook Integration
Requires no kernel changes. Distributed as dependency:
@file:DependsOn("sk.ai:skainet-display:0.1.0")
12. Delivery Plan
| Phase |
Output |
| M1 |
Base image renderer |
| M2 |
Multi-source support |
| M3 |
Grid + styling DSL |
| M4 |
Docs + notebook samples |
13. Risks
| Risk |
Mitigation |
| HTML restrictions |
SVG fallback |
| Memory usage |
Auto-downscale very large images |
| Performance issues |
Cache base64 results |
14. Success Metrics
- ≤5 lines to display any image
- Zero Swing UI windows
- Used in ≥3 real skainet demos
15. References
16. MVP Code Sketch
object KVImage {
fun display(img: BufferedImage, opts: DisplayOptions = DisplayOptions()) {
val base64 = img.toBase64()
HTML("""
<img src="data:image/png;base64,$base64"
${opts.width?.let { "width='$it'" } ?: ""}
${opts.height?.let { "height='$it'" } ?: ""}
alt="${opts.alt}"
style="${if (opts.border) "border:1px solid #ccc;" else ""}">
""").display()
}
}
PRD – Kotlin Notebook Image Rendering for Computer Vision
1. Overview
Goal:
Provide a simple, Kotlin-native, notebook-friendly way to render images inline inside Kotlin notebooks for computer vision workflows, comparable in ease of use to Python’s
PIL.Image.show()ordisplay().Target users:
Leverages Kotlin Notebook rich output APIs:
https://kotlinlang.org/docs/data-analysis-notebooks-output-formats.html#rich-text
2. Problem Statement
Kotlin notebooks currently lack a clean, idiomatic way to show images inline. Typical approaches:
JFrame)2.1 Reference: Python PIL API
In Python notebooks the workflow is extremely concise and expressive:
Key qualities to match:
The Kotlin solution must aim to replicate this experience from a developer ergonomics standpoint.
3. Objectives
Deliver a small utility module that:
4. User Stories
US-01 – Display from BufferedImage
US-02 – Display from file path
display("assets/sample.jpg")US-03 – Display from ByteArray
US-04 – Display with sizing options
display(img) { width = 256 height = 256 }US-05 – Multi-image display
display(listOf(img1, img2, img3))5. Functional Requirements
Supported Inputs
BufferedImageByteArrayString,PathURLOutput Rendering
<img>HTML tagsdata:image/*;base64)HTML(...))Styling Controls
Optional DSL settings:
width,heightalttextbordertogglecssClassBatch / Grid Mode
Lists render as responsive image rows or grids.
6. Non-Functional Requirements
7. API Design
Core function
Overloads
Options DSL
8. Implementation Strategy
Rendering model
Injected via:
HTML(htmlString).display()Conversion utilities
Dispatcher
Grid HTML layout
9. Example Notebook Usage
10. Developer Experience
11. skainet-notebook Integration
Requires no kernel changes. Distributed as dependency:
@file:DependsOn("sk.ai:skainet-display:0.1.0")12. Delivery Plan
13. Risks
14. Success Metrics
15. References
Kotlin Notebook Rich Output:
https://kotlinlang.org/docs/data-analysis-notebooks-output-formats.html#rich-text
skainet-notebook:
https://github.com/sk-ai-net/skainet-notebook
Python PIL Display Pattern:
https://pillow.readthedocs.io/
https://ipython.readthedocs.io/
16. MVP Code Sketch