[framework] lerp images in a save layer. (#131703)

Without a saveLayer, the BlendMode.plus will add itself to the backdrop and not just the previous image. Pushing without tests to see if existing goldens fail, but otherwise I have some good examples locally.

This is necessary uncondtionally, and lerping lerped images has the same issue.

Fixes https://github.com/flutter/flutter/issues/131617

### Before

![flutter_02](https://github.com/flutter/flutter/assets/8975114/1e783285-2fc2-429f-9fd8-6d04d4a155e1)

### After

![flutter_03](https://github.com/flutter/flutter/assets/8975114/3d08b187-26aa-4471-926d-e9ed5946a206)
diff --git a/packages/flutter/lib/src/painting/decoration_image.dart b/packages/flutter/lib/src/painting/decoration_image.dart
index c91a9f0..66c1be2 100644
--- a/packages/flutter/lib/src/painting/decoration_image.dart
+++ b/packages/flutter/lib/src/painting/decoration_image.dart
@@ -815,8 +815,10 @@
 
   @override
   void paint(Canvas canvas, Rect rect, Path? clipPath, ImageConfiguration configuration, { double blend = 1.0, BlendMode blendMode = BlendMode.srcOver }) {
+    canvas.saveLayer(null, Paint());
     a?.paint(canvas, rect, clipPath, configuration, blend: blend * (1.0 - t), blendMode: blendMode);
     b?.paint(canvas, rect, clipPath, configuration, blend: blend * t, blendMode: a != null ? BlendMode.plus : blendMode);
+    canvas.restore();
   }
 
   @override
diff --git a/packages/flutter/test/painting/decoration_image_lerp_test.dart b/packages/flutter/test/painting/decoration_image_lerp_test.dart
index 1e0f6f4..44d2e3e 100644
--- a/packages/flutter/test/painting/decoration_image_lerp_test.dart
+++ b/packages/flutter/test/painting/decoration_image_lerp_test.dart
@@ -405,6 +405,169 @@
       expect(getPixelFromBlock(19, 19, 19), const Color(0xFF000000));
     }
   }, skip: kIsWeb); // TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609
+
+  testWidgets('ImageDecoration.lerp with colored background', (WidgetTester tester) async {
+    final MemoryImage cmyk = MemoryImage(Uint8List.fromList(<int>[
+      0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,  0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,  0x02, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x9f, 0x76,
+      0xed, 0x00, 0x00, 0x00, 0x0c, 0x50, 0x4c, 0x54,  0x45, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff,
+      0xff, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x4c, 0x59,  0x13, 0x00, 0x00, 0x00, 0x0e, 0x49, 0x44, 0x41,
+      0x54, 0x08, 0xd7, 0x63, 0x60, 0x05, 0xc2, 0xf5,  0x0c, 0xeb, 0x01, 0x03, 0x00, 0x01, 0x69, 0x19,
+      0xea, 0x34, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x49,  0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+    ]));
+    final MemoryImage wrgb = MemoryImage(Uint8List.fromList(<int>[
+      0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,  0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,  0x02, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x9f, 0x76,
+      0xed, 0x00, 0x00, 0x00, 0x0c, 0x50, 0x4c, 0x54,  0x45, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00,
+      0xff, 0x00, 0xff, 0x00, 0x00, 0x1e, 0x46, 0xbb,  0x1c, 0x00, 0x00, 0x00, 0x0e, 0x49, 0x44, 0x41,
+      0x54, 0x08, 0xd7, 0x63, 0xe0, 0x07, 0xc2, 0xa5,  0x0c, 0x4b, 0x01, 0x03, 0x50, 0x01, 0x69, 0x4a,
+      0x78, 0x1d, 0x41, 0x00, 0x00, 0x00, 0x00, 0x49,  0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+    ]));
+
+    await tester.runAsync(() async {
+      await load(cmyk);
+      await load(wrgb);
+    });
+
+    await tester.pumpWidget(
+      ColoredBox(
+        color: Colors.pink,
+        child: Align(
+          alignment: Alignment.topLeft,
+          child: Wrap(
+            textDirection: TextDirection.ltr,
+            children: <Widget>[
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                0.0,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                0.1,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                0.2,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                0.8,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                0.9,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.contain),
+                DecorationImage(image: cmyk, fit: BoxFit.contain),
+                1.0,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, fit: BoxFit.cover),
+                DecorationImage(image: cmyk, repeat: ImageRepeat.repeat),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, repeat: ImageRepeat.repeat),
+                DecorationImage(image: cmyk, repeat: ImageRepeat.repeatY),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, repeat: ImageRepeat.repeatX),
+                DecorationImage(image: cmyk, repeat: ImageRepeat.repeat),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, repeat: ImageRepeat.repeat, opacity: 0.2),
+                DecorationImage(image: cmyk, repeat: ImageRepeat.repeat, opacity: 0.2),
+                0.25,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, repeat: ImageRepeat.repeat, opacity: 0.2),
+                DecorationImage(image: cmyk, repeat: ImageRepeat.repeat, opacity: 0.2),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, repeat: ImageRepeat.repeat, opacity: 0.2),
+                DecorationImage(image: cmyk, repeat: ImageRepeat.repeat, opacity: 0.2),
+                0.75,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: wrgb, scale: 0.5, repeat: ImageRepeat.repeatX),
+                DecorationImage(image: cmyk, scale: 0.25, repeat: ImageRepeat.repeatY),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.0,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.25,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.75,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                1.0,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(0.0, 0.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.0,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(0.0, 0.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.25,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(0.0, 0.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.5,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(0.0, 0.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                0.75,
+              )),
+              TestImage(DecorationImage.lerp(
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(0.0, 0.0, 1.0, 1.0)),
+                DecorationImage(image: cmyk, centerSlice: const Rect.fromLTWH(2.0, 2.0, 1.0, 1.0)),
+                1.0,
+              )),
+            ],
+          ),
+        ),
+      ),
+    );
+
+    await expectLater(
+      find.byType(Wrap),
+      matchesGoldenFile('decoration_image.lerp.2.png'),
+    );
+  }, skip: kIsWeb); // TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609
 }
 
 Future<void> load(MemoryImage image) {