You can get code from a Docker image by starting a container from that image, copying the source files out with docker cp, and then rendering the recovered text as a clean PNG with the Code to Image Generator, all without uploading the code to a remote server. The Docker side of the workflow uses the standard Docker CLI on your own machine, so the extraction runs through the local Docker daemon and writes to a path you control. The image-rendering side happens entirely inside your browser tab: the tool pastes the text onto a Canvas at natural size using a local monospace font stack, encodes the bitmap as a PNG, and offers code-image.png as a download. Because the input is always treated as inert text and never parsed, executed, or injected as HTML, a snippet that looks like JavaScript or HTML stays as ordinary glyphs on the canvas. Every step is local: nothing about the original source leaves your computer at any point, and the resulting PNG stores pixels rather than editable source.

Three ways to read code out of a Docker image
Docker images are layered filesystems, and the Docker CLI ships three practical commands for reading the text inside them. Each method trades off how much of the image you need to start, how clean the output is, and whether file permissions survive the trip. The right choice depends on whether you want an exact copy of one file, a quick peek at a small snippet, or a full offline audit of every layer.
| Method | Best for | Starts a container? | Preserves file modes | Output format |
|---|---|---|---|---|
| docker create + docker cp | Exact file or directory copies | Briefly (stopped) | Yes | Local path |
| docker run --rm + shell stream | Short snippets, quick look | Yes (removed after) | No (stdout text) | Plain text on stdout |
| docker save + tar -x | Offline auditing of every layer | No | Yes (in tar) | Layer tarballs |
The first method is the most common when you need a single file or a small subtree and you already know its path inside the image. The second method is the lightest touch, useful when you want to peek at a config file or a short script without leaving any container state behind. The third method is the only one that does not require the image to actually run on your machine, which matters when the image is large, comes from an untrusted registry, or targets a different CPU architecture than your host.
Copy files out of a container with docker cp
The cleanest one-shot extraction for a known file path uses docker create to make a stopped container from the image, docker cp to copy the file out of that container's filesystem, and docker rm to throw the stopped container away. No process inside the image ever has to run, which keeps the surface area small and avoids triggering entrypoints that might expect environment variables you have not set.
- Pull or load the image. Run docker pull example/app:1.2.3 if the image is on a registry, or docker load -i app.tar if you have a saved tarball.
- Create a stopped container from the image. Run docker create --name app-shell example/app:1.2.3. The container exists but is not started, so no entrypoint script runs.
- Copy the file or directory out. Run docker cp app-shell:/app/src ./src. The first path is the path inside the container; the second is the destination on your host. Directories copy recursively and keep their contents intact.
- Inspect what you copied. Run ls -la ./src and wc -l ./src/*.py to confirm the file is intact and to see how many lines you are about to render.
- Remove the stopped container. Run docker rm app-shell so the unused container does not accumulate on your host.
For very small text snippets where starting a container feels heavy, a one-liner with docker run --rm works just as well: docker run --rm example/app:1.2.3 cat /app/src/main.py streams the file contents to your terminal without keeping the container afterward. This path skips the copy step but loses the file's permissions and timestamps, which is fine when you only care about the characters themselves.
Render the recovered code as a PNG with the Code to Image Generator
Once the source sits in a local file, the next step is to paste it into the Code to Image Generator and let the browser rasterize it as a PNG. The tool runs entirely in your current tab, so the text never leaves your machine on the way to the image either. For a deeper walk-through of the rendering side, see this in-browser PNG rendering walk-through.
- Open the tool and paste the source. Open the Code to Image Generator, then paste the full file contents into the text area. Empty lines and the final newline are preserved as image rows, so leave the structure exactly as it appears in the file.
- Pick a theme, font size, and padding. Choose a light or dark palette, set a font size between 12 and 32 pixels, and choose a padding between 16 and 96 pixels. Each option is a fixed whole number, so the result summary reports the actual dimensions assigned to the offscreen Canvas.
- Generate the PNG. Click the generate button. The tool measures every complete line with the local monospace stack, allocates a bounded Canvas at natural size, paints an opaque background, draws each line with fillText, and encodes the finished bitmap as image/png.
- Check the preview and the summary. Confirm the on-screen preview, the reported pixel dimensions, the line count, and the PNG size. The exported file comes from the natural-size offscreen Canvas, so what you download is not silently downsampled to fit the preview.
- Download code-image.png. Click the download button to save the PNG. Stale or replaced generations have their local object URLs revoked, so the only live download is the one that matches the options currently shown.
If the input is over the limit, the tool rejects it with an explicit error instead of cropping or shrinking the output. The hard ceilings are 50,000 UTF-16 code units across the whole input, 200 logical lines, 2,000 code units on any single line, 8,192 pixels per Canvas edge, 32 million pixels of total area, and a 20 MiB PNG.
How the tool measures and paints the text
The PNG dimensions are computed from the chosen font size and padding, not from a fixed template. The line height is the ceiling of one and one-half times the font size, so a 20-pixel font produces a 30-pixel line height. For a 100-line snippet at that font with 24 pixels of padding on the top and bottom, the Canvas height becomes ceil(20 × 1.5) × 100 + 2 × 24, which is 30 × 100 + 48, or 3,048 pixels. The width uses measureText on every preserved line after the font is set, takes the largest finite measured width, rounds the content extent upward, and adds padding on both sides so the text never gets clipped at the right edge.
After the Canvas is resized, the drawing context is reacquired and the font, baseline, alignment, direction, kerning, background, and foreground are explicitly reapplied. Resizing a Canvas resets its state, so this reapplication is what keeps the output consistent for the same options. The Canvas is then painted with the selected opaque background and every line is drawn left-aligned from the same padding position with a top baseline. Blank lines consume their full row even though they paint no glyph, which is why trailing newlines and empty middle lines stay visible as image rows.
What the PNG keeps and what it drops
The downloaded file is a PNG of pixels. It does not contain the editable source, syntax structure, font files, runtime output, or any tokenization that would let someone recover the original characters back into a code editor. The same input and options should produce stable measurements in the same browser and font environment, but pixel-identical output across computers is not promised, because the browser resolves the declared monospace stack from locally available fonts and fallback glyphs can change the rasterized edges.
The tool uses a single foreground color and does not perform language-aware syntax highlighting, so the PNG cannot claim to show tokens, keywords, or comments in different colors. It is also not a code editor, compiler, sandbox, secret scanner, syntax validator, formatter, OCR system, or accessibility replacement for selectable source. Review the recovered text for credentials, tokens, private URLs, and personal information before sharing the PNG, and keep the original file separately whenever editability, exact character recovery, or accessibility matters.
When a PNG of code is the right share format
A code PNG is the right format when the destination cannot be trusted with editable text, when the snippet needs to render the same way in chat clients, social posts, and issue trackers, and when visual consistency matters more than copy-paste fidelity. It is a poor format when the reader needs to run the code, search inside it, or copy it back into an editor, because the PNG offers no way to recover the original characters.
Practical cases that fit the PNG format include documenting a configuration example in a wiki, attaching a small reproducer to a bug report, illustrating a tutorial post, and showing a function signature on social media. For everything that requires round-trip editing, pair the PNG with the original file or paste the text alongside it, and reach for the Code to Image Generator only for the visual half of the artifact.