adding packages

This commit is contained in:
2026-01-15 14:38:46 -08:00
parent ef86e3ab6a
commit 6869cf47e5
5253 changed files with 726695 additions and 34 deletions
@@ -0,0 +1,6 @@
library image_resizer;
export 'src/folders.dart';
export 'src/generator.dart';
export 'src/template.dart';
export 'src/generator/impl.dart';
@@ -0,0 +1,108 @@
import 'template.dart';
abstract class ImageFolder {
final String path;
final List<IconTemplate> templates;
ImageFolder(this.path, this.templates);
}
class WebIconsFolder extends ImageFolder {
WebIconsFolder({
String path = 'web/icons',
this.favicion,
List<WebIcon> icons = _defaultIcons,
}) : super(path, icons);
static const _defaultIcons = [
WebIcon(size: 192),
WebIcon(size: 512),
];
final WebFavicon favicion;
}
class IosIconsFolder extends ImageFolder {
IosIconsFolder({
String path = 'ios/Runner/Assets.xcassets/AppIcon.appiconset',
List<IosIcon> icons = _defaultIcons,
}) : super(path, icons);
static const _defaultIcons = [
IosIcon(size: 20, scale: 1),
IosIcon(size: 20, scale: 2),
IosIcon(size: 20, scale: 3),
IosIcon(size: 29, scale: 1),
IosIcon(size: 29, scale: 2),
IosIcon(size: 29, scale: 3),
IosIcon(size: 40, scale: 1),
IosIcon(size: 40, scale: 2),
IosIcon(size: 40, scale: 3),
IosIcon(size: 60, scale: 2),
IosIcon(size: 60, scale: 3),
IosIcon(size: 76, scale: 1),
IosIcon(size: 76, scale: 2),
IosIcon(size: 83, scale: 2, point5: true),
IosIcon(size: 1024, scale: 1),
];
Map<String, dynamic> toJson({int version = 1, String author = 'xcode'}) {
return {
"images": [
for (var icon in this.templates) ...{
if (icon is IosIcon) ...{
icon.toJson(),
},
}
],
"info": {"version": version, "author": author}
};
}
}
class MacOSIconsFolder extends ImageFolder {
MacOSIconsFolder({
String path = 'macos/Runner/Assets.xcassets/AppIcon.appiconset',
List<MacOSIcon> icons = _defaultIcons,
}) : super(path, icons);
static const _defaultIcons = [
MacOSIcon(size: 16, scale: 1, name: '16'),
MacOSIcon(size: 16, scale: 2, name: '32'),
MacOSIcon(size: 32, scale: 1, name: '32'),
MacOSIcon(size: 32, scale: 2, name: '64'),
MacOSIcon(size: 128, scale: 1, name: '128'),
MacOSIcon(size: 128, scale: 2, name: '256'),
MacOSIcon(size: 256, scale: 1, name: '256'),
MacOSIcon(size: 256, scale: 2, name: '512'),
MacOSIcon(size: 512, scale: 1, name: '512'),
MacOSIcon(size: 512, scale: 2, name: '1024'),
];
Map<String, dynamic> toJson({int version = 1, String author = 'xcode'}) {
return {
"images": [
for (var icon in this.templates) ...{
if (icon is IosIcon) ...{
icon.toJson(),
},
}
],
"info": {"version": version, "author": author}
};
}
}
class AndroidIconsFolder extends ImageFolder {
AndroidIconsFolder({
String path = 'android/app/src/main/res',
List<AndroidIcon> icons = _defaultIcons,
}) : super(path, icons);
static const _defaultIcons = [
AndroidIcon(size: 72, folderSuffix: "hdpi"),
AndroidIcon(size: 48, folderSuffix: "mdpi"),
AndroidIcon(size: 96, folderSuffix: "xhdpi"),
AndroidIcon(size: 144, folderSuffix: "xxhdpi"),
AndroidIcon(size: 192, folderSuffix: "xxxhdpi"),
];
}
@@ -0,0 +1,3 @@
export 'generator/unsupported.dart'
if (dart.library.html) 'generator/web.dart'
if (dart.library.io) 'generator/io.dart';
@@ -0,0 +1,94 @@
import 'package:archive/archive.dart';
import 'package:image/image.dart';
import 'package:path/path.dart' as p;
import 'package:image_resizer/src/folders.dart';
import 'package:image_resizer/src/template.dart';
export 'package:image_resizer/src/folders.dart';
export 'package:image_resizer/src/template.dart';
abstract class IconGeneratorImpl {
Future<FileData> generateIcon(Image image, IconTemplate icon,
{String path = '', bool writeToDiskIO = true}) async {
final Image resizedIcon = createResizedImage(icon, image);
String filename = icon.filename;
final data = encodeNamedImage(resizedIcon, filename);
final _path = p.joinAll([
path,
if (icon is AndroidIcon) ...[
icon.folder + '-' + icon.folderSuffix,
],
filename
]);
return FileData(data, data.length, filename, _path);
}
Future<List<FileData>> generateIcons(Image image, ImageFolder folder,
{String path = '', bool writeToDiskIO = true}) async {
final List<FileData> _images = [];
for (var template in folder.templates) {
final _icon = await generateIcon(
image,
template,
path: p.joinAll([if (path.isNotEmpty) path, folder.path]),
writeToDiskIO: writeToDiskIO,
);
_images.add(_icon);
}
return _images;
}
List<int> generateArchive(List<FileData> images) {
var encoder = ZipEncoder();
final _output = OutputStream();
encoder.startEncode(_output);
// final archive = Archive();
for (var f in images) {
final archiveFile = ArchiveFile(f.path, f.size, f.data);
encoder.addFile(archiveFile);
}
encoder.endEncode();
return _output.getBytes();
}
}
Image createResizedImage(IconTemplate template, Image image) {
Interpolation _interpolation;
if (image.width >= template.size) {
_interpolation = Interpolation.average;
} else {
_interpolation = Interpolation.linear;
}
if (template is IosIcon) {
return copyResize(
image,
width: (template.adjustedSize * template.scale.toDouble()).round(),
height: (template.adjustedSize * template.scale.toDouble()).round(),
interpolation: _interpolation,
);
}
if (template is MacOSIcon) {
return copyResize(
image,
width: template.size * template.scale,
height: template.size * template.scale,
interpolation: _interpolation,
);
}
return copyResize(
image,
width: template.size,
height: template.size,
interpolation: _interpolation,
);
}
class FileData {
final List<int> data;
final int size;
final String name;
final String path;
FileData(this.data, this.size, this.name, this.path);
}
@@ -0,0 +1,75 @@
import 'dart:convert';
import 'package:image/image.dart';
import 'impl.dart';
import 'dart:io';
import 'package:path/path.dart' as p;
class IconGenerator extends IconGeneratorImpl {
@override
Future<List<FileData>> generateIcons(Image image, ImageFolder folder,
{String path = '', bool writeToDiskIO = true}) async {
final List<FileData> _images = [];
final _folderPath = p.joinAll([if (path.isNotEmpty) path, folder.path]);
for (var template in folder.templates) {
final _icon = await generateIcon(
image,
template,
path: _folderPath,
writeToDiskIO: writeToDiskIO,
);
_images.add(_icon);
}
if (writeToDiskIO) {
if (folder is IosIconsFolder) {
final _file = File(p.join(_folderPath, 'Contents.json'));
if (!_file.existsSync()) {
await _file.create(recursive: true);
}
await _file.writeAsString(json.encode(folder.toJson()));
}
if (folder is MacOSIconsFolder) {
final _file = File(p.join(_folderPath, 'Contents.json'));
if (!_file.existsSync()) {
await _file.create(recursive: true);
}
await _file.writeAsString(json.encode(folder.toJson()));
}
}
return _images;
}
@override
Future<FileData> generateIcon(Image image, IconTemplate icon,
{String path = '', bool writeToDiskIO = true}) async {
if (path == '') {
path = Directory.current.path;
}
File _file = File(p.joinAll([
path,
icon.filename,
]));
if (writeToDiskIO && !_file.existsSync()) {
await _file.createSync(recursive: true);
}
final Image resizedIcon = createResizedImage(icon, image);
final filename = icon.filename;
final data = encodeNamedImage(resizedIcon, filename);
if (writeToDiskIO) {
_file = await _file.writeAsBytes(data);
print('Updated: $filename');
}
return FileData(
data,
data.length,
filename,
p.joinAll([
path,
if (icon is AndroidIcon) ...[
icon.folder + '-' + icon.folderSuffix,
],
filename
]));
}
}
@@ -0,0 +1,3 @@
import 'impl.dart';
class IconGenerator extends IconGeneratorImpl {}
@@ -0,0 +1,3 @@
import 'impl.dart';
class IconGenerator extends IconGeneratorImpl {}
@@ -0,0 +1,191 @@
import 'dart:convert';
import 'package:meta/meta.dart';
/// Template for Icon
abstract class IconTemplate {
const IconTemplate(this.size);
final int size;
String get filename;
}
/// web/icons/Icon-512.png
class WebIcon extends IconTemplate {
const WebIcon({
@required int size,
this.prefix = 'Icon-',
this.ext = 'png',
}) : super(size);
final String prefix;
final String ext;
WebIcon copyWith({
int size,
String prefix,
String ext,
}) {
return WebIcon(
prefix: prefix ?? this.prefix,
size: size ?? this.size,
ext: ext ?? this.ext,
);
}
Map<String, dynamic> toJson([String folder = "icons"]) {
return {
"src": "$folder/$filename",
"sizes": "$size" + "x" + "$size",
"type": "image/$ext"
};
}
@override
String get filename => '$prefix$size.$ext';
}
/// web/icons/Icon-512.png
class WebFavicon extends IconTemplate {
const WebFavicon({
int size = 16,
this.name = 'favicon',
this.ext = 'png',
}) : super(size);
final String name;
final String ext;
WebFavicon copyWith({
int size,
String name,
String ext,
}) {
return WebFavicon(
size: size ?? this.size,
ext: ext ?? this.ext,
name: name ?? this.name,
);
}
@override
String get filename => '$name.$ext';
}
/// ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
class IosIcon extends IconTemplate {
const IosIcon({
@required int size,
this.ext = 'png',
this.prefix = 'Icon-App-',
this.scale = 1,
this.point5 = false,
}) : super(size);
final String prefix;
final int scale;
final String ext;
final bool point5;
IosIcon copyWith({
int size,
String prefix,
int scale,
String ext,
bool point5,
}) {
return IosIcon(
size: size ?? this.size,
prefix: prefix ?? this.prefix,
scale: scale ?? this.scale,
ext: ext ?? this.ext,
point5: point5 ?? this.point5,
);
}
Map<String, dynamic> toJson() {
return {
"size": "${size}x${size}",
"idiom": "ios-marketing",
"filename": filename,
"scale": "${scale}x"
};
}
double get adjustedSize => point5 ? (size.toDouble() + 0.5) : size.toDouble();
@override
String get filename =>
"$prefix${adjustedSize}x${adjustedSize}@${scale}x.$ext";
}
/// android/app/src/main/res/mipmap-hdpi/ic_launcher.png
class AndroidIcon extends IconTemplate {
const AndroidIcon({
@required int size,
this.name = 'ic_launcher',
this.ext = 'png',
this.folderSuffix = 'mipmap-',
this.folder = 'hdpi',
}) : super(size);
final String name;
final String folder;
final String folderSuffix;
final String ext;
AndroidIcon copyWith({
String name,
String folder,
String folderSuffix,
String ext,
int size,
}) {
return AndroidIcon(
name: name ?? this.name,
size: size ?? this.size,
folder: folder ?? this.folder,
folderSuffix: folderSuffix ?? this.folderSuffix,
ext: ext ?? this.ext,
);
}
@override
String get filename => "$name.$ext";
}
/// macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
class MacOSIcon extends IconTemplate {
const MacOSIcon({
@required int size,
this.prefix = 'app_icon_',
this.ext = 'png',
this.scale = 1,
this.name = '16',
}) : super(size);
final String prefix;
final int scale;
final String ext;
final String name;
MacOSIcon copyWith({
int size,
String prefix,
int scale,
String ext,
}) {
return MacOSIcon(
size: size ?? this.size,
prefix: prefix ?? this.prefix,
scale: scale ?? this.scale,
ext: ext ?? this.ext,
);
}
Map<String, dynamic> toJson() {
return {
"size": "$size" + "x" + "$size",
"idiom": "mac",
"filename": "$prefix$name.$ext",
"scale": "${scale}x"
};
}
@override
String get filename => "$prefix$name.$ext";
}