Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/NesTiler.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2022-10-23 20:45:53 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2022-10-23 20:45:53 +0300
commit7dd48d7271047e2d18cc92d2fb0d3d4e9f62cb53 (patch)
tree77e1def438bcd11482517f73203c0f695035213c /NesTiler
parent2059d5e112e8a9bb0064c132677bd723154af424 (diff)
Optimization.
Diffstat (limited to 'NesTiler')
-rw-r--r--NesTiler/ColorExtensions.cs6
-rw-r--r--NesTiler/FastBitmap.cs61
-rw-r--r--NesTiler/Palette.cs4
-rw-r--r--NesTiler/Program.cs36
4 files changed, 82 insertions, 25 deletions
diff --git a/NesTiler/ColorExtensions.cs b/NesTiler/ColorExtensions.cs
index d3d70be..39a48df 100644
--- a/NesTiler/ColorExtensions.cs
+++ b/NesTiler/ColorExtensions.cs
@@ -42,8 +42,10 @@ namespace com.clusterrr.Famicom.NesTiler
public static Color GetPixelColor(this SKBitmap image, int x, int y)
{
- var skColor = image.GetPixel(x, y);
- var color = Color.FromArgb(skColor.Red, skColor.Green, skColor.Blue);
+ //var skColor = image.GetPixel(x, y);
+ var b = image.Bytes;
+ var offset = image.RowBytes * y + x * image.BytesPerPixel;
+ var color = Color.FromArgb(b[offset + 3], b[offset + 2], b[offset + 1], b[offset + 0]);
return color;
}
diff --git a/NesTiler/FastBitmap.cs b/NesTiler/FastBitmap.cs
new file mode 100644
index 0000000..2ee9081
--- /dev/null
+++ b/NesTiler/FastBitmap.cs
@@ -0,0 +1,61 @@
+using SkiaSharp;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace com.clusterrr.Famicom.NesTiler
+{
+ public class FastBitmap
+ {
+ public int Width { get; }
+ public int Height { get; }
+
+ private readonly Color[] colors;
+ private static Dictionary<string, SKBitmap> imagesCache = new Dictionary<string, SKBitmap>();
+
+ private FastBitmap(SKBitmap skBitmap, int verticalOffset = 0, int height = 0)
+ {
+ Width = skBitmap.Width;
+ Height = height <= 0 ? skBitmap.Height - verticalOffset : height;
+ var pixels = skBitmap.Pixels;
+ colors = skBitmap.Pixels.Skip(verticalOffset * Width).Take(Width * Height).Select(p => Color.FromArgb(p.Alpha, p.Red, p.Green, p.Blue)).ToArray();
+ }
+
+ public static FastBitmap Decode(string filename, int verticalOffset = 0, int height = 0)
+ {
+ using var image = SKBitmap.Decode(filename);
+ if (image == null) return null;
+ imagesCache[filename] = image;
+ return new FastBitmap(image, verticalOffset, height);
+ }
+
+ public Color GetPixelColor(int x, int y)
+ {
+ return colors[y * Width + x];
+ }
+
+ public void SetPixelColor(int x, int y, Color color)
+ {
+ colors[y * Width + x] = color;
+ }
+
+ public byte[] Encode(SKEncodedImageFormat format, int v)
+ {
+ using var skImage = new SKBitmap(Width, Height);
+ for (int y = 0; y < Height; y++)
+ {
+ for (int x = 0; x < Width; x++)
+ {
+ var color = colors[y * Width + x];
+ var skColor = new SKColor(color.R, color.G, color.B);
+ skImage.SetPixel(x, y, skColor);
+ }
+ }
+ return skImage.Encode(format, v).ToArray();
+ }
+ }
+}
diff --git a/NesTiler/Palette.cs b/NesTiler/Palette.cs
index 6835dd2..0dc31ff 100644
--- a/NesTiler/Palette.cs
+++ b/NesTiler/Palette.cs
@@ -33,7 +33,7 @@ namespace com.clusterrr.Famicom.NesTiler
// Empty palette
}
- public Palette(SKBitmap image, int leftX, int topY, int width, int height, Color bgColor)
+ public Palette(FastBitmap image, int leftX, int topY, int width, int height, Color bgColor)
{
Dictionary<Color, int> colorCounter = new Dictionary<Color, int>();
for (int y = topY; y < topY + height; y++)
@@ -69,7 +69,7 @@ namespace com.clusterrr.Famicom.NesTiler
if (colorsList.Count > i) this[i + 1] = colorsList[i];
}
- public double GetTileDelta(SKBitmap image, int leftX, int topY, int width, int height, Color bgColor)
+ public double GetTileDelta(FastBitmap image, int leftX, int topY, int width, int height, Color bgColor)
{
double delta = 0;
for (int y = topY; y < topY + height; y++)
diff --git a/NesTiler/Program.cs b/NesTiler/Program.cs
index 2695502..c8b34c3 100644
--- a/NesTiler/Program.cs
+++ b/NesTiler/Program.cs
@@ -95,7 +95,7 @@ namespace com.clusterrr.Famicom.NesTiler
bool quiet = false;
// Data
- var images = new Dictionary<int, SKBitmap>();
+ var images = new Dictionary<int, FastBitmap>();
var paletteIndexes = new Dictionary<int, byte[,]>();
var patternTables = new Dictionary<int, Dictionary<int, Tile>>();
var nameTables = new Dictionary<int, List<int>>();
@@ -278,33 +278,27 @@ namespace com.clusterrr.Famicom.NesTiler
}
// Loading images
- foreach (var image in imageFiles)
+ foreach (var imageFile in imageFiles)
{
- console($"Loading file #{image.Key} - {Path.GetFileName(image.Value)}...");
+ console($"Loading file #{imageFile.Key} - {Path.GetFileName(imageFile.Value)}...");
var offsetRegex = new Regex(@"^(?<filename>.*?)(:(?<offset>[0-9]+)(:(?<height>[0-9]+))?)?$");
- var match = offsetRegex.Match(image.Value);
+ var match = offsetRegex.Match(imageFile.Value);
var filename = match.Groups["filename"].Value;
- if (!File.Exists(filename)) throw new FileNotFoundException($"File {filename} not found");
- images[image.Key] = SKBitmap.Decode(filename);
- if (images[image.Key] == null) throw new InvalidDataException($"Can't load {filename}");
var offsetS = match.Groups["offset"].Value;
var heightS = match.Groups["height"].Value;
// Crop it if need
+ int offset = 0;
+ int height = 0;
if (!string.IsNullOrEmpty(offsetS))
{
- int offset = int.Parse(offsetS);
- int height = images[image.Key].Height - offset;
- if (!string.IsNullOrEmpty(heightS))
- height = int.Parse(heightS);
- console($"Cropping it to {offset}:{height}...");
- var cropped = new SKBitmap(images[image.Key].Width, height);
- using (SKCanvas bitmapCanvas = new SKCanvas(cropped))
- {
- bitmapCanvas.DrawBitmap(images[image.Key], 0, -offset);
- }
- images[image.Key].Dispose();
- images[image.Key] = cropped;
+ offset = int.Parse(offsetS);
+ if (!string.IsNullOrEmpty(heightS)) height = int.Parse(heightS);
}
+ if (!File.Exists(filename)) throw new FileNotFoundException($"File {filename} not found");
+ var image = FastBitmap.Decode(filename, offset, height);
+ if (image == null) throw new InvalidDataException($"Can't load {filename}");
+ images[imageFile.Key] = image;
+
//if ((imagesOriginal[image.Key].Width % tilePalWidth != 0) || (imagesOriginal[image.Key].Height % tilePalHeight != 0))
// throw new InvalidDataException("Invalid image size");
// TODO: more image size checks
@@ -496,7 +490,7 @@ namespace com.clusterrr.Famicom.NesTiler
// Save preview if required
if (outPreview.ContainsKey(imageNum))
{
- File.WriteAllBytes(outPreview[imageNum], image.Encode(SKEncodedImageFormat.Png, 0).ToArray());
+ File.WriteAllBytes(outPreview[imageNum], image.Encode(SKEncodedImageFormat.Png, 0));
console($"Preview #{imageNum} saved to {outPreview[imageNum]}");
}
}
@@ -684,7 +678,7 @@ namespace com.clusterrr.Famicom.NesTiler
}
}
- static Palette[] CalculatePalettes(Dictionary<int, SKBitmap> images, bool[] paletteEnabled, Palette[] fixedPalettes, Dictionary<int, int> attributeTableOffsets, int tilePalWidth, int tilePalHeight, Color bgColor)
+ static Palette[] CalculatePalettes(Dictionary<int, FastBitmap> images, bool[] paletteEnabled, Palette[] fixedPalettes, Dictionary<int, int> attributeTableOffsets, int tilePalWidth, int tilePalHeight, Color bgColor)
{
var required = Enumerable.Range(0, 4).Select(i => paletteEnabled[i] && fixedPalettes[i] == null);
// Creating and counting the palettes