Skip to content

Commit

Permalink
feat: Adding ImageExtension.resize (#2418)
Browse files Browse the repository at this point in the history
Adds a helper method to ImageExtension to make it easier to resize an image.
  • Loading branch information
erickzanardo authored Mar 31, 2023
1 parent 1576bd8 commit a3f1601
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 2 deletions.
2 changes: 2 additions & 0 deletions examples/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'package:examples/stories/components/components.dart';
import 'package:examples/stories/effects/effects.dart';
import 'package:examples/stories/experimental/experimental.dart';
import 'package:examples/stories/games/games.dart';
import 'package:examples/stories/image/image.dart';
import 'package:examples/stories/input/input.dart';
import 'package:examples/stories/layout/layout.dart';
import 'package:examples/stories/parallax/parallax.dart';
Expand Down Expand Up @@ -77,6 +78,7 @@ void runAsDashbook() {
addSystemStories(dashbook);
addUtilsStories(dashbook);
addWidgetsStories(dashbook);
addImageStories(dashbook);

// Bridge package examples
addForge2DStories(dashbook);
Expand Down
23 changes: 23 additions & 0 deletions examples/lib/stories/image/image.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:dashbook/dashbook.dart';

import 'package:examples/commons/commons.dart';
import 'package:examples/stories/image/resize.dart';
import 'package:flame/game.dart';

void addImageStories(Dashbook dashbook) {
dashbook.storiesOf('Image')
..decorator(CenterDecorator())
..add(
'resize',
(context) => GameWidget(
game: ImageResizeExample(
Vector2(
context.numberProperty('width', 200),
context.numberProperty('height', 300),
),
),
),
codeLink: baseLink('image/resize.dart'),
info: ImageResizeExample.description,
);
}
29 changes: 29 additions & 0 deletions examples/lib/stories/image/resize.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flame/components.dart';
import 'package:flame/extensions.dart';
import 'package:flame/game.dart';

class ImageResizeExample extends FlameGame {
ImageResizeExample(this.sizeTarget);

static const String description = '''
Shows how a dart:ui `Image` can be resized using Flame Image extensions.
Use the properties on the side to change the size of the image.
''';

final Vector2 sizeTarget;

@override
Future<void> onLoad() async {
final image = await images.load('flame.png');

final resized = await image.resize(sizeTarget);
add(
SpriteComponent(
sprite: Sprite(resized),
position: size / 2,
size: resized.size,
anchor: Anchor.center,
),
);
}
}
3 changes: 2 additions & 1 deletion examples/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ dependencies:
padracing: ^1.0.0
provider: ^6.0.3
rogue_shooter: ^0.1.0
test: ^1.23.1
trex_game: ^0.1.0

dev_dependencies:
flame_lint: ^0.2.0
test: any

flutter:
uses-material-design: true

Expand Down
25 changes: 24 additions & 1 deletion packages/flame/lib/src/extensions/image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';

import 'package:flame/src/extensions/color.dart';
import 'package:flame/palette.dart';
import 'package:flame/src/extensions/vector2.dart';

export 'dart:ui' show Image;

extension ImageExtension on Image {
static final Paint _whitePaint = BasicPalette.white.paint();

/// Converts a raw list of pixel values into an [Image] object.
///
/// The pixels must be in the RGBA format, i.e. first 4 bytes encode the red,
Expand Down Expand Up @@ -90,4 +92,25 @@ extension ImageExtension on Image {
}
return fromPixels(newPixelData, width, height);
}

/// Resizes this image to the given [newSize].
///
/// Keep in mind that is considered an expensive operation and should be
/// avoided in the the game loop methods. Prefer using it
/// in the loading phase of the game or components.
Future<Image> resize(Vector2 newSize) async {
final recorder = PictureRecorder();
Canvas(recorder).drawImageRect(
this,
getBoundingRect(),
newSize.toRect(),
_whitePaint,
);
final picture = recorder.endRecording();
final resizedImage = await picture.toImage(
newSize.x.toInt(),
newSize.y.toInt(),
);
return resizedImage;
}
}
16 changes: 16 additions & 0 deletions packages/flame/test/extensions/image_extension_test.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui';

import 'package:flame/extensions.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

final output = List.filled(8 * 8 * 4, 255);
Expand Down Expand Up @@ -151,5 +153,19 @@ void main() {
);
expect(orignalBrightenPixelsList, expectedBrightenPixels);
});

test('resize resizes the image', () async {
final recorder = PictureRecorder();
Canvas(recorder).drawRect(
const Rect.fromLTWH(0, 0, 100, 100),
Paint()..color = Colors.white,
);
final pic = recorder.endRecording();
final image = await pic.toImage(100, 100);

final resizedImage = await image.resize(Vector2(200, 400));
expect(resizedImage.width, equals(200));
expect(resizedImage.height, equals(400));
});
});
}

0 comments on commit a3f1601

Please sign in to comment.