exec method

  1. @override
Future<void> exec(
  1. ExecContext context
)
override

Run command.

The contents of katana.yaml and the arguments of the command are passed to context.

コマンドを実行します。

contextkatana.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));
          }
        }
      }
    }
  }
}