TODO
diff --git a/sparse_strips/vello_bench/src/pixmap.rs b/sparse_strips/vello_bench/src/pixmap.rs
index a0fecd5..dfd3f6d 100644
--- a/sparse_strips/vello_bench/src/pixmap.rs
+++ b/sparse_strips/vello_bench/src/pixmap.rs
@@ -41,7 +41,7 @@
     group.bench_function("take_unpremultiplied", |b| {
         b.iter_batched(
             || pixmap.clone(),
-            |pixmap| black_box(pixmap.take_unpremultiplied()),
+            |pixmap| black_box(pixmap.take(ImageAlphaType::Alpha)),
             BatchSize::LargeInput,
         );
     });
diff --git a/sparse_strips/vello_common/src/pixmap.rs b/sparse_strips/vello_common/src/pixmap.rs
index ae65391..95b05da 100644
--- a/sparse_strips/vello_common/src/pixmap.rs
+++ b/sparse_strips/vello_common/src/pixmap.rs
@@ -9,10 +9,7 @@
 use std::io::{BufRead, Seek};
 
 use crate::fearless_simd::{Level, Simd, SimdBase, SimdInt, SimdMask, dispatch, mask8x16};
-use crate::peniko::{
-    ImageAlphaType,
-    color::{PremulRgba8, Rgba8},
-};
+use crate::peniko::{ImageAlphaType, color::PremulRgba8};
 use crate::util::Div255Ext;
 
 #[cfg(feature = "png")]
@@ -312,7 +309,7 @@
         encoder.set_color(png::ColorType::Rgba);
         encoder.set_depth(png::BitDepth::Eight);
         let mut writer = encoder.write_header()?;
-        writer.write_image_data(bytemuck::cast_slice(&self.take_unpremultiplied()))?;
+        writer.write_image_data(&self.take(ImageAlphaType::Alpha))?;
         writer.finish().map(|_| data)
     }
 
@@ -386,37 +383,30 @@
         self.buf[idx] = pixel;
     }
 
-    /// Consume the pixmap, returning the data as the underlying [`Vec`] of premultiplied RGBA8.
+    /// Consume the pixmap, returning its RGBA8 bytes with the requested alpha representation.
     ///
-    /// The pixels are in row-major order.
-    pub fn take(self) -> Vec<PremulRgba8> {
-        self.buf
-    }
-
-    /// Consume the pixmap, returning the data as (unpremultiplied) RGBA8.
-    ///
-    /// Not fast, but useful for saving to PNG etc.
-    ///
-    /// The pixels are in row-major order.
-    pub fn take_unpremultiplied(self) -> Vec<Rgba8> {
-        self.buf
-            .into_iter()
-            .map(|PremulRgba8 { r, g, b, a }| {
-                let alpha = 255.0 / f32::from(a);
-                if a != 0 {
-                    #[expect(clippy::cast_possible_truncation, reason = "deliberate quantization")]
-                    let unpremultiply = |component| (f32::from(component) * alpha + 0.5) as u8;
-                    Rgba8 {
-                        r: unpremultiply(r),
-                        g: unpremultiply(g),
-                        b: unpremultiply(b),
-                        a,
+    /// The pixels are in row-major order. Note that it's always cheapest to call this method
+    /// with [`ImageAlphaType::AlphaPremultiplied`] since this is the internal representation
+    /// of the pixmap.
+    pub fn take(self, alpha_type: ImageAlphaType) -> Vec<u8> {
+        let mut data = bytemuck::cast_vec(self.buf);
+        if alpha_type == ImageAlphaType::Alpha {
+            for pixel in data.chunks_exact_mut(4) {
+                let alpha = pixel[3];
+                if alpha != 0 {
+                    let scale = 255.0 / f32::from(alpha);
+                    for component in &mut pixel[..3] {
+                        #[expect(
+                            clippy::cast_possible_truncation,
+                            reason = "deliberate quantization"
+                        )]
+                        let unpremultiplied = (f32::from(*component) * scale + 0.5) as u8;
+                        *component = unpremultiplied;
                     }
-                } else {
-                    Rgba8 { r, g, b, a }
                 }
-            })
-            .collect()
+            }
+        }
+        data
     }
 }
 
@@ -585,4 +575,24 @@
         assert!(!pixmap.may_have_transparency());
         assert_eq!(pixmap.data_as_u8_slice(), data);
     }
+
+    #[test]
+    fn take_returns_requested_alpha_type_as_bytes() {
+        let data = vec![100, 50, 25, 128, 9, 8, 7, 255, 1, 2, 3, 0];
+        let pixmap = Pixmap::from_parts(
+            data.clone(),
+            3,
+            1,
+            PixelMetadata::new(ImageAlphaType::AlphaPremultiplied, true),
+        );
+
+        assert_eq!(
+            pixmap.clone().take(ImageAlphaType::AlphaPremultiplied),
+            data
+        );
+        assert_eq!(
+            pixmap.take(ImageAlphaType::Alpha),
+            [199, 100, 50, 128, 9, 8, 7, 255, 1, 2, 3, 0]
+        );
+    }
 }
diff --git a/sparse_strips/vello_common/src/probe.rs b/sparse_strips/vello_common/src/probe.rs
index 3982fff..a898644 100644
--- a/sparse_strips/vello_common/src/probe.rs
+++ b/sparse_strips/vello_common/src/probe.rs
@@ -11,8 +11,8 @@
 use crate::kurbo::{Affine, BezPath, Circle, Point, Rect, Shape};
 use crate::paint::{Image, ImageSource, PaintType};
 use crate::peniko::{
-    BlendMode, ColorStop, ColorStops, Compose, Extend, Gradient, ImageQuality, ImageSampler,
-    LinearGradientPosition, Mix,
+    BlendMode, ColorStop, ColorStops, Compose, Extend, Gradient, ImageAlphaType, ImageQuality,
+    ImageSampler, LinearGradientPosition, Mix,
 };
 use crate::pixmap::Pixmap;
 use alloc::vec::Vec;
@@ -207,7 +207,7 @@
         Self {
             width: pixmap.width(),
             height: pixmap.height(),
-            data: bytemuck::cast_slice(&pixmap.take_unpremultiplied()).to_vec(),
+            data: pixmap.take(ImageAlphaType::Alpha),
         }
     }
 }
diff --git a/sparse_strips/vello_hybrid/examples/render_to_file.rs b/sparse_strips/vello_hybrid/examples/render_to_file.rs
index a075f28..f0e0ceb 100644
--- a/sparse_strips/vello_hybrid/examples/render_to_file.rs
+++ b/sparse_strips/vello_hybrid/examples/render_to_file.rs
@@ -8,6 +8,7 @@
 
 use std::io::BufWriter;
 use vello_common::kurbo::{Affine, Stroke};
+use vello_common::peniko::ImageAlphaType;
 use vello_common::pico_svg::{Item, PicoSvg};
 use vello_common::pixmap::{PixelMetadata, Pixmap};
 use vello_hybrid::{DimensionConstraints, Scene};
@@ -169,7 +170,7 @@
     png_encoder.set_color(png::ColorType::Rgba);
     let mut writer = png_encoder.write_header().unwrap();
     writer
-        .write_image_data(bytemuck::cast_slice(&pixmap.take_unpremultiplied()))
+        .write_image_data(&pixmap.take(ImageAlphaType::Alpha))
         .unwrap();
 }
 
diff --git a/sparse_strips/vello_sparse_tests/src/regenerate_probe_reference.rs b/sparse_strips/vello_sparse_tests/src/regenerate_probe_reference.rs
index 3b2c40d..7ade707 100644
--- a/sparse_strips/vello_sparse_tests/src/regenerate_probe_reference.rs
+++ b/sparse_strips/vello_sparse_tests/src/regenerate_probe_reference.rs
@@ -3,7 +3,6 @@
 
 //! Regenerate the probe reference assets in `vello_common/assets`.
 
-use bytemuck::cast_slice;
 use std::{
     path::PathBuf,
     sync::{Arc, LazyLock},
@@ -15,7 +14,7 @@
     filter_effects::Filter,
     kurbo::{Affine, BezPath, Rect},
     paint::{ImageSource, PaintType},
-    peniko::BlendMode,
+    peniko::{BlendMode, ImageAlphaType},
     pixmap::Pixmap,
     probe::{self, ProbeRenderer},
 };
@@ -102,7 +101,7 @@
 
 fn build_probe_reference_data() -> ProbeReferenceData {
     let pixmap = render_probe_pixmap();
-    let rgba = cast_slice(&pixmap.clone().take_unpremultiplied()).to_vec();
+    let rgba = pixmap.clone().take(ImageAlphaType::Alpha);
     let png = pixmap.into_png().unwrap();
     #[cfg(not(target_arch = "wasm32"))]
     let png = oxipng::optimize_from_memory(&png, &Options::max_compression()).unwrap();
diff --git a/sparse_strips/vello_toy/src/svg.rs b/sparse_strips/vello_toy/src/svg.rs
index f3fb9a3..2dba965 100644
--- a/sparse_strips/vello_toy/src/svg.rs
+++ b/sparse_strips/vello_toy/src/svg.rs
@@ -19,7 +19,7 @@
 use usvg::{Node, Paint, PaintOrder};
 use vello_cpu::color::AlphaColor;
 use vello_cpu::kurbo::{Affine, BezPath, Stroke};
-use vello_cpu::peniko::Fill;
+use vello_cpu::peniko::{Fill, ImageAlphaType};
 use vello_cpu::{Level, Pixmap, RenderContext, RenderSettings, Resources};
 
 fn main() {
@@ -68,14 +68,14 @@
 }
 
 fn write_pixmap(pixmap: &mut Pixmap) {
-    let data = pixmap.clone().take_unpremultiplied();
+    let data = pixmap.clone().take(ImageAlphaType::Alpha);
 
     let mut png_data = Vec::new();
     let cursor = Cursor::new(&mut png_data);
     let encoder = PngEncoder::new(cursor);
     encoder
         .write_image(
-            bytemuck::cast_slice(&data),
+            &data,
             pixmap.width() as u32,
             pixmap.height() as u32,
             ExtendedColorType::Rgba8,