This commit is contained in:
Vadim 2024-05-14 16:15:19 +02:00
parent 2540aa9364
commit ea023f49e1
5 changed files with 33 additions and 33 deletions

2
.gitignore vendored
View file

@ -63,4 +63,4 @@ ios/Runner/GoogleService-Info.plist
coverage/ coverage/
test/coverage_helper_test.dart test/coverage_helper_test.dart
**/failures/*.png **/failures/*.png
screenshots/generated/raw/ screenshots/generated/

View file

@ -30,8 +30,7 @@ extension ScreenshotImage on Image {
args.backgroundColor.a, args.backgroundColor.a,
), ),
) )
._applyLayout(layout) ._applyLayout(
._addText(
layout, layout,
_configs[args.name]!.title, _configs[args.name]!.title,
_configs[args.name]!.subtitle, _configs[args.name]!.subtitle,
@ -75,16 +74,20 @@ extension ScreenshotImage on Image {
return compositeImage(expandedScreenshot, frame); return compositeImage(expandedScreenshot, frame);
} }
Image _applyLayout(ScreenshotLayout layout) { Image _applyLayout(ScreenshotLayout layout, String title, String subtitle, {required bool isDark}) {
final scaledScreenshot = copyResize( final textImage = _drawTitles(layout, title, subtitle, isDark: isDark);
this, final maxFrameHeight =
width: layout.size.width - (layout.contentPadding.left + layout.contentPadding.right), layout.size.height - (layout.contentPadding.top + textImage.height + 84 + layout.contentPadding.bottom);
); int maxFrameWidth = layout.size.width - (layout.contentPadding.left + layout.contentPadding.right);
if (maxFrameWidth * height / width > maxFrameHeight) {
maxFrameWidth = maxFrameHeight * width ~/ height;
}
final scaledScreenshot = copyResize(this, width: maxFrameWidth);
return copyExpandCanvas( final draft = copyExpandCanvas(
copyExpandCanvas( copyExpandCanvas(
scaledScreenshot, scaledScreenshot,
newWidth: scaledScreenshot.width + layout.contentPadding.right, newWidth: scaledScreenshot.width + (layout.size.width - scaledScreenshot.width) ~/ 2,
newHeight: scaledScreenshot.height + layout.contentPadding.bottom, newHeight: scaledScreenshot.height + layout.contentPadding.bottom,
position: ExpandCanvasPosition.topLeft, position: ExpandCanvasPosition.topLeft,
backgroundColor: getPixel(0, 0), backgroundColor: getPixel(0, 0),
@ -94,9 +97,16 @@ extension ScreenshotImage on Image {
position: ExpandCanvasPosition.bottomRight, position: ExpandCanvasPosition.bottomRight,
backgroundColor: getPixel(0, 0), backgroundColor: getPixel(0, 0),
); );
return compositeImage(
draft,
textImage,
dstX: layout.contentPadding.left,
dstY: layout.contentPadding.top,
);
} }
Image _addText(ScreenshotLayout layout, String title, String subtitle, {required bool isDark}) { Image _drawTitles(ScreenshotLayout layout, String title, String subtitle, {required bool isDark}) {
final titleFont = final titleFont =
BitmapFont.fromZip(File(isDark ? layout.titleFontDarkPath : layout.titleFontPath).readAsBytesSync()); BitmapFont.fromZip(File(isDark ? layout.titleFontDarkPath : layout.titleFontPath).readAsBytesSync());
final subtitleFont = final subtitleFont =
@ -127,11 +137,6 @@ extension ScreenshotImage on Image {
subtitleDy += subtitleFont.lineHeight; subtitleDy += subtitleFont.lineHeight;
}); });
return compositeImage( return textImage;
this,
textImage,
dstX: layout.contentPadding.left,
dstY: layout.contentPadding.top,
);
} }
} }

View file

@ -13,7 +13,8 @@ Future<int> main(List<String> args) async {
final parser = ArgParser() final parser = ArgParser()
..addFlag('verbose', abbr: 'v', help: 'Verbose output.') ..addFlag('verbose', abbr: 'v', help: 'Verbose output.')
..addOption('platform', abbr: 'p', help: 'Device platform.', mandatory: true) ..addOption('platform', abbr: 'p', help: 'Device platform.', mandatory: true)
..addOption('device', abbr: 'd', help: 'device_snake_name', mandatory: true); ..addOption('device', abbr: 'd', help: 'device_snake_name', mandatory: true)
..addOption('layout', abbr: 'l', help: 'Device platform.', mandatory: true);
final ArgResults argResults = parser.parse(args); final ArgResults argResults = parser.parse(args);
if (argResults['verbose'] as bool) { if (argResults['verbose'] as bool) {
@ -22,8 +23,10 @@ Future<int> main(List<String> args) async {
Logger.root.level = Level.INFO; Logger.root.level = Level.INFO;
} }
final device = argResults["device"] as String;
final platform = argResults["platform"] as String; final platform = argResults["platform"] as String;
final device = argResults["device"] as String;
final layout = ScreenshotLayout.values.firstWhere((e) => e.name == argResults["layout"] as String);
Directory('screenshots/generated/raw/$platform/$device').listSync().forEach((filePath) async { Directory('screenshots/generated/raw/$platform/$device').listSync().forEach((filePath) async {
final screenshotName = filePath.path.split('/').last.replaceAll('.png', ''); final screenshotName = filePath.path.split('/').last.replaceAll('.png', '');
final screenshotBytes = File(filePath.path).readAsBytesSync(); final screenshotBytes = File(filePath.path).readAsBytesSync();
@ -43,12 +46,13 @@ Future<int> main(List<String> args) async {
isDark: filePath.path.contains('dark-'), isDark: filePath.path.contains('dark-'),
); );
final file = await File(filePath.path.replaceAll('/raw', '')).create(recursive: true); final file =
await File('screenshots/generated/$platform/${layout.name}/$screenshotName.png').create(recursive: true);
file.writeAsBytesSync( file.writeAsBytesSync(
encodePng( encodePng(
screenshot.convertToStoreScreenshot( screenshot.convertToStoreScreenshot(
args: screenshotArgs, args: screenshotArgs,
layout: ScreenshotLayout.iphone65inch, layout: layout,
), ),
), ),
); );

View file

@ -1,13 +1,13 @@
enum ScreenshotLayout { enum ScreenshotLayout {
iphone65inch( iphone65inch(
size: (width: 1242, height: 2688), size: (width: 1242, height: 2688),
contentPadding: (left: 150, top: 192, right: 150, bottom: 192), contentPadding: (left: 144, top: 184, right: 144, bottom: 184),
titleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Bold.zip', titleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Bold.zip',
subtitleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Regular.zip', subtitleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Regular.zip',
), ),
iphone55inch( iphone55inch(
size: (width: 1242, height: 2208), size: (width: 1242, height: 2208),
contentPadding: (left: 150, top: 192, right: 150, bottom: 192), contentPadding: (left: 144, top: 144, right: 144, bottom: 144),
titleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Bold.zip', titleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Bold.zip',
subtitleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Regular.zip', subtitleFontPath: 'screenshots/assets/fonts/SF-Pro-Display-Regular.zip',
); );

View file

@ -1,24 +1,15 @@
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:image/image.dart';
import 'package:integration_test/integration_test_driver_extended.dart'; import 'package:integration_test/integration_test_driver_extended.dart';
import '../screenshots/convert_to_store_screenshot.dart';
import '../screenshots/models/screenshot_args.dart'; import '../screenshots/models/screenshot_args.dart';
import '../screenshots/models/screenshot_layout.dart';
Future<void> main() async { Future<void> main() async {
await integrationDriver( await integrationDriver(
onScreenshot: (name, bytes, [_]) async { onScreenshot: (name, bytes, [_]) async {
final screenshotArgs = ScreenshotArgs.fromString(name); final screenshotArgs = ScreenshotArgs.fromString(name);
final file = await File(screenshotArgs.toPathRaw()).create(recursive: true); final file = await File(screenshotArgs.toPathRaw()).create(recursive: true);
final screenshot = decodePng(Uint8List.fromList(bytes))!.convertToStoreScreenshot( file.writeAsBytesSync(bytes);
args: screenshotArgs,
layout: ScreenshotLayout.iphone65inch,
);
file.writeAsBytesSync(encodePng(screenshot));
return true; return true;
}, },
); );