exec method
Run command.
The contents of katana.yaml
and the arguments of the command are passed to context
.
コマンドを実行します。
context
にkatana.yaml
の内容やコマンドの引数が渡されます。
Implementation
@override
Future<void> exec(ExecContext context) async {
final store = context.yaml.getAsMap("store");
final screenshot = store.getAsMap("screenshot");
final exportDir = screenshot.get("export_dir", "").trimStringRight("/");
final colorCode = screenshot.get("color", "").trimString("#");
final orientation = screenshot.get("orientation", "");
final sourceDir = screenshot.get("source_dir", "");
final featureImageSourcePath = screenshot.get("feature_image", "");
final title = screenshot.get("title", "");
final iconSourcePath = screenshot.get("icon", "");
final purchasePosition = screenshot.get("purchase_position", "center");
final iconPosition = screenshot.getAsMap("icon_position", {});
final iconPositionX = iconPosition.getAsInt("x", 12);
final iconPositionY = iconPosition.getAsInt("y", 12);
if (exportDir.isEmpty) {
error(
"[store]->[screenshot]->[export_dir] is not found. Fill in the destination folder here.",
);
return;
}
if (sourceDir.isEmpty) {
error(
"[store]->[screenshot]->[source_dir] is not found. Fill in the source folder here.",
);
return;
}
if (colorCode.isEmpty) {
error(
"[store]->[screenshot]->[color] is not found. Enter the color code for the background color here.",
);
return;
}
label("Retrieve the source.");
// 色の変換
final backgroundColor = ColorUint8.rgb(
int.parse(colorCode.substring(0, 2), radix: 16),
int.parse(colorCode.substring(2, 4), radix: 16),
int.parse(colorCode.substring(4, 6), radix: 16),
);
final foregroundColor = ColorUint8.rgb(255, 255, 255);
final document = Directory(exportDir);
if (!document.existsSync()) {
document.createSync(recursive: true);
}
final source = Directory(sourceDir);
if (!source.existsSync()) {
source.createSync(recursive: true);
}
final root = source.path.replaceAll(r"\", "/");
final sources = source.listSync().where((file) {
final path = file.path.replaceAll(r"\", "/").replaceAll("$root/", "");
if (path.startsWith(".") || path.contains("/.")) {
return false;
}
return true;
}).toList();
label("Create a featured image.");
final featureImage = File("$exportDir/feature_image.png");
if (featureImageSourcePath.isNotEmpty) {
final featureImageSource = File(featureImageSourcePath);
if (featureImageSource.existsSync()) {
final source = decodeImage(featureImageSource.readAsBytesSync())!;
final resized = copyResize(source, width: 1024);
final cropped = copyCrop(
resized,
x: 0,
y: ((resized.height - 500) / 2.0).floor(),
width: resized.width,
height: 500,
);
featureImage.writeAsBytesSync(encodePng(cropped));
}
}
if (!featureImage.existsSync()) {
var image = Image(
width: 1024,
height: 500,
)..clear(backgroundColor);
if (title.isNotEmpty) {
image = drawString(
image,
title,
font: arial48,
x: 1008,
y: 448,
rightJustify: true,
color: foregroundColor,
);
}
featureImage.writeAsBytesSync(encodePng(image));
}
label("Create a icon.");
final iconImage = File("$exportDir/icon.png");
final iconImageAndroid = File("$exportDir/icon_android.png");
if (iconSourcePath.isNotEmpty) {
final iconSource = File(iconSourcePath);
if (iconSource.existsSync()) {
final source = decodeImage(iconSource.readAsBytesSync())!;
final resized = copyResize(source, width: 1024);
final cropped = copyCrop(
resized,
x: 0,
y: ((resized.height - 500) / 2.0).floor(),
width: resized.width,
height: 500,
);
iconImage.writeAsBytesSync(encodePng(cropped));
}
}
if (!iconImage.existsSync()) {
if (title.isNotEmpty) {
var image = Image(
width: 64,
height: 64,
);
image = drawString(
image,
title.substring(0, 1).toUpperCase(),
font: arial48,
x: iconPositionX,
y: iconPositionY,
color: foregroundColor,
);
image = _adjustAlpha(
copyResize(
image,
width: 1024,
maintainAspect: true,
interpolation: Interpolation.linear,
),
foregroundColor: foregroundColor,
backgroundColor: backgroundColor,
);
iconImage.writeAsBytesSync(encodePng(image));
} else {
final image = Image(
width: 1024,
height: 1024,
)..clear(backgroundColor);
iconImage.writeAsBytesSync(encodePng(image));
}
}
final iconSource = decodeImage(iconImage.readAsBytesSync())!;
final resized = copyResize(
iconSource,
width: 512,
height: 512,
maintainAspect: true,
);
iconImageAndroid.writeAsBytesSync(encodePng(resized));
label("Create other screenshots.");
if (sources.isEmpty) {
for (final tmp in _resolution.entries) {
if (tmp.key != orientation) {
continue;
}
for (final val in tmp.value.entries) {
final key = val.key;
final size = val.value;
if (key == "purchase") {
final file = File("$exportDir/${key}_0.png");
if (file.existsSync()) {
continue;
}
final image = Image(width: size.width, height: size.height)
..clear(backgroundColor);
file.writeAsBytesSync(encodePng(image));
} else {
for (int i = 0; i < 2; i++) {
final file = File("$exportDir/${key}_$i.png");
if (file.existsSync()) {
continue;
}
final image = Image(width: size.width, height: size.height)
..clear(backgroundColor);
file.writeAsBytesSync(encodePng(image));
}
}
}
}
} else {
sources.sort((a, b) {
return a.path.compareTo(b.path);
});
for (final tmp in _resolution.entries) {
if (tmp.key != orientation) {
continue;
}
for (final val in tmp.value.entries) {
final key = val.key;
final size = val.value;
for (int i = 0; i < sources.length; i++) {
if (key == "icon") {
} else if (key == "purchase") {
final file = File(sources[i].path);
final image = decodeImage(file.readAsBytesSync())!;
if (orientation == "portrait") {
final offset = _getOffset(size.height);
final resized = copyResize(image, width: size.width);
final cropped = copyCrop(
resized,
x: 0,
y: _purchaseVerticalPosition(
sourceHeight: resized.height,
targetHeight: size.height,
position: purchasePosition,
offset: offset,
).floor(),
width: resized.width,
height: size.height,
);
File("$exportDir/${key}_$i.png")
.writeAsBytesSync(encodePng(cropped));
} else {
final resized = copyResize(image, height: size.height);
final cropped = copyCrop(
resized,
x: ((resized.width - size.width) / 2.0).floor(),
y: 0,
width: size.width,
height: resized.height,
);
File("$exportDir/${key}_$i.png")
.writeAsBytesSync(encodePng(cropped));
}
} else {
final file = File(sources[i].path);
final image = Image(width: size.width, height: size.height)
..clear(backgroundColor);
final sourceFile = decodeImage(file.readAsBytesSync())!;
final offset = _getOffset(sourceFile.height);
final sourceImage = dropShadow(
_resize(
_crop(
sourceFile,
offset.top,
offset.bottom,
),
image,
64,
64,
64,
64,
),
16,
16,
16,
);
final merged = compositeImage(
image,
sourceImage,
dstX: ((image.width / 2) - (sourceImage.width / 2)).round(),
dstY: ((image.height / 2) - (sourceImage.height / 2)).round(),
);
File("$exportDir/${key}_$i.png")
.writeAsBytesSync(encodePng(merged));
}
}
}
}
}
}