Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor from System.Drawing.Common to Skiasharp. #1538

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
22ceca0
Refactor from System.Drawing.Common to Skiasharp.
Miepee Nov 15, 2023
c26eb75
Some UI fixes.
VladiStep Dec 24, 2023
9e841c6
Implement GMS 2 tile flag rendering.
VladiStep Dec 25, 2023
9faf60b
A little optimization of `CreateLayerSource()`
VladiStep Dec 25, 2023
ce38b10
Remove redundant DLL import and uncomment one line.
VladiStep Dec 26, 2023
c55aeab
Simplify disposal of the disposable objects.
VladiStep Dec 26, 2023
1067b9b
Minor code improvements for "TextureWorker.cs".
VladiStep Dec 26, 2023
61b975b
Improve performance of some methods in `TextureWorker`.
VladiStep Dec 26, 2023
ca437af
Minor code improvements for "QoiConverter.cs".
VladiStep Dec 26, 2023
c677100
Fix a crash on exporting all frames of a sprite,
VladiStep Dec 26, 2023
f74955a
Remove all references of "System.Drawing" from the lib and GUI.
VladiStep Dec 26, 2023
a8331c7
Remove all references of "System.Drawing" from the scripts (WIP)
VladiStep Dec 26, 2023
0c21988
Revert scripts changes
VladiStep Dec 27, 2023
77d5725
Add useful methods and one argument to `TextureWorker`.
VladiStep Dec 27, 2023
0ea44e8
Add missing comments for tile transformations.
VladiStep Dec 27, 2023
f693c8a
Remove a redundant DLL import.
VladiStep Dec 27, 2023
f843311
Add reminder comments for tile transformation part.
VladiStep Dec 27, 2023
98364cb
Add a comment with a warning.
VladiStep Dec 27, 2023
a720cd7
Remove unneccesary `SKBitmap.SetImmutable()` call.
VladiStep Dec 27, 2023
a8337d0
Revert the `QoiConverter.GetImageFromSpan()` comment change.
VladiStep Dec 27, 2023
2ba06eb
Replace "System.Drawing" with "SkiaSharp" in all scripts. (#24)
VladiStep Jun 2, 2024
7309147
add todos to scripts which are windows only
Miepee Jun 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions UndertaleModLib/Models/UndertaleEmbeddedTexture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
using System;
using System.Buffers.Binary;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using SkiaSharp;
using UndertaleModLib.Util;

namespace UndertaleModLib.Models;
Expand Down Expand Up @@ -408,7 +408,7 @@ public void Serialize(FileBinaryWriter writer, bool gm2022_3, bool gm2022_5)
writer.Write(QOIAndBZip2Header);

// Encode the PNG data back to QOI+BZip2
using Bitmap bmp = TextureWorker.GetImageFromByteArray(TextureBlob);
using SKBitmap bmp = TextureWorker.GetImageFromByteArray(TextureBlob);
writer.Write((short)bmp.Width);
writer.Write((short)bmp.Height);
byte[] qoiData = QoiConverter.GetArrayFromImage(bmp, gm2022_3 ? 0 : 4);
Expand All @@ -423,7 +423,7 @@ public void Serialize(FileBinaryWriter writer, bool gm2022_3, bool gm2022_5)
else
{
// Encode the PNG data back to QOI
using Bitmap bmp = TextureWorker.GetImageFromByteArray(TextureBlob);
using SKBitmap bmp = TextureWorker.GetImageFromByteArray(TextureBlob);
writer.Write(QoiConverter.GetSpanFromImage(bmp, gm2022_3 ? 0 : 4));
}
}
Expand Down Expand Up @@ -464,9 +464,9 @@ public void Unserialize(IBinaryReader reader, bool gm2022_5)
sharedStream.Seek(0, SeekOrigin.Begin);
BZip2.Decompress(reader.Stream, sharedStream, false);
ReadOnlySpan<byte> decompressed = sharedStream.GetBuffer().AsSpan()[..(int)sharedStream.Position];
using Bitmap bmp = QoiConverter.GetImageFromSpan(decompressed);
using SKBitmap bmp = QoiConverter.GetImageFromSpan(decompressed);
sharedStream.Seek(0, SeekOrigin.Begin);
bmp.Save(sharedStream, ImageFormat.Png);
bmp.Encode(sharedStream, SKEncodedImageFormat.Png, 100);
TextureBlob = new byte[(int)sharedStream.Position];
sharedStream.Seek(0, SeekOrigin.Begin);
sharedStream.Read(TextureBlob, 0, TextureBlob.Length);
Expand All @@ -478,10 +478,10 @@ public void Unserialize(IBinaryReader reader, bool gm2022_5)
FormatBZ2 = false;

// Need to convert the QOI data to PNG for compatibility purposes (at least for now)
using Bitmap bmp = QoiConverter.GetImageFromStream(reader.Stream);
using SKBitmap bmp = QoiConverter.GetImageFromStream(reader.Stream);
if (sharedStream.Length != 0)
sharedStream.Seek(0, SeekOrigin.Begin);
bmp.Save(sharedStream, ImageFormat.Png);
bmp.Encode(sharedStream, SKEncodedImageFormat.Png, 100);
TextureBlob = new byte[(int)sharedStream.Position];
sharedStream.Seek(0, SeekOrigin.Begin);
sharedStream.Read(TextureBlob, 0, TextureBlob.Length);
Expand Down
15 changes: 7 additions & 8 deletions UndertaleModLib/Models/UndertaleRoom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -490,7 +489,7 @@ public void SetupRoom(bool calculateGridWidth = true, bool calculateGridHeight =

// Automatically set the grid size to whatever most tiles are sized

Dictionary<Point, uint> tileSizes = new();
Dictionary<(int w, int h), uint> tileSizes = new();
IEnumerable<Tile> tileList;

if (Layers.Count > 0)
Expand All @@ -502,9 +501,9 @@ public void SetupRoom(bool calculateGridWidth = true, bool calculateGridHeight =
tileList = tileList.Concat(layer.AssetsData.LegacyTiles);
else if (layer.LayerType == LayerType.Tiles && layer.TilesData.TileData.Length != 0)
{
int w = (int) (Width / layer.TilesData.TilesX);
int h = (int) (Height / layer.TilesData.TilesY);
tileSizes[new(w, h)] = layer.TilesData.TilesX * layer.TilesData.TilesY;
int w = (int)(Width / layer.TilesData.TilesX);
int h = (int)(Height / layer.TilesData.TilesY);
tileSizes[(w, h)] = layer.TilesData.TilesX * layer.TilesData.TilesY;
}
}

Expand All @@ -515,7 +514,7 @@ public void SetupRoom(bool calculateGridWidth = true, bool calculateGridHeight =
// Loop through each tile and save how many times their sizes are used
foreach (Tile tile in tileList)
{
Point scale = new((int) tile.Width, (int) tile.Height);
(int w, int h) scale = ((int)tile.Width, (int)tile.Height);
if (tileSizes.ContainsKey(scale))
tileSizes[scale]++;
else
Expand All @@ -535,9 +534,9 @@ public void SetupRoom(bool calculateGridWidth = true, bool calculateGridHeight =
// If tiles exist at all, grab the most used tile size and use that as our grid size
var largestKey = tileSizes.Aggregate((x, y) => x.Value > y.Value ? x : y).Key;
if (calculateGridWidth)
GridWidth = largestKey.X;
GridWidth = largestKey.w;
if (calculateGridHeight)
GridHeight = largestKey.Y;
GridHeight = largestKey.h;
}

/// <inheritdoc />
Expand Down
13 changes: 6 additions & 7 deletions UndertaleModLib/Models/UndertaleTexturePageItem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.ComponentModel;
using System.Drawing;
using SkiaSharp;
using UndertaleModLib.Util;

namespace UndertaleModLib.Models;
Expand Down Expand Up @@ -146,19 +146,18 @@ public void Dispose()
/// </summary>
/// <param name="replaceImage">The new image that shall be applied to this texture page item.</param>
/// <param name="disposeImage">Whether to dispose <paramref name="replaceImage"/> afterwards.</param>
public void ReplaceTexture(Image replaceImage, bool disposeImage = true)
public void ReplaceTexture(SKBitmap replaceImage, bool disposeImage = true)
{
Image finalImage = TextureWorker.ResizeImage(replaceImage, SourceWidth, SourceHeight);
SKBitmap finalImage = TextureWorker.ResizeImage(replaceImage, SourceWidth, SourceHeight);

// Apply the image to the TexturePage.
lock (TexturePage.TextureData)
{
TextureWorker worker = new TextureWorker();
Bitmap embImage = worker.GetEmbeddedTexture(TexturePage); // Use SetPixel if needed.
SKBitmap embImage = worker.GetEmbeddedTexture(TexturePage); // Use SetPixel if needed.

Graphics g = Graphics.FromImage(embImage);
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
g.DrawImage(finalImage, SourceX, SourceY);
SKCanvas g = new(embImage);
g.DrawBitmap(finalImage, SourceX, SourceY);
g.Dispose();

TexturePage.TextureData.TextureBlob = TextureWorker.GetImageBytes(embImage);
Expand Down
4 changes: 2 additions & 2 deletions UndertaleModLib/UndertaleModLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
</PackageReference>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Drawing.Common" Version="5.0.3" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="SkiaSharp" Version="2.88.6" />
</ItemGroup>
<ItemGroup>
<None Remove="version.txt" />
Expand Down
51 changes: 21 additions & 30 deletions UndertaleModLib/Util/QoiConverter.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using SkiaSharp;

namespace UndertaleModLib.Util
{
Expand Down Expand Up @@ -46,12 +45,12 @@
}

/// <summary>
/// Creates a <see cref="Bitmap"/> from a <see cref="Stream"/>.
/// Creates a <see cref="SKBitmap"/> from a <see cref="Stream"/>.
/// </summary>
/// <param name="s">The stream to create the PNG image from.</param>
/// <returns>The QOI image as a PNG.</returns>
/// <exception cref="Exception">If there is an invalid QOIF magic header or there was an error with stride width.</exception>
public static Bitmap GetImageFromStream(Stream s)
public static SKBitmap GetImageFromStream(Stream s)
{
Span<byte> header = stackalloc byte[12];
s.Read(header);
Expand All @@ -63,19 +62,18 @@
}

/// <summary>
/// Creates a <see cref="Bitmap"/> from a <see cref="ReadOnlySpan{TKey}"/> of <see cref="byte"/>s.
/// Creates a <see cref="SKBitmap"/> from a <see cref="ReadOnlySpan{TKey}"/> of <see cref="byte"/>s.
/// </summary>
/// <param name="bytes">The <see cref="Span{TKey}"/> of <see cref="byte"/>s to create the PNG image from.</param>
/// <param name="bytes">The <see cref="ReadOnlySpan{TKey}"/> of <see cref="byte"/>s to create the PNG image from.</param>
/// <returns>The QOI image as a PNG.</returns>
/// <exception cref="Exception">If there is an invalid QOIF magic header or there was an error with stride width.</exception>
public static Bitmap GetImageFromSpan(ReadOnlySpan<byte> bytes) => GetImageFromSpan(bytes, out _);
public static SKBitmap GetImageFromSpan(ReadOnlySpan<byte> bytes) => GetImageFromSpan(bytes, out _);

/// <summary><inheritdoc cref="GetImageFromSpan(System.ReadOnlySpan{byte})"/></summary>
/// <param name="bytes"><inheritdoc cref="GetImageFromSpan(System.ReadOnlySpan{byte})"/></param>
/// <param name="length">The total amount of data read from the <see cref="Span{TKey}"/>.</param>
/// <returns><inheritdoc cref="GetImageFromSpan(System.ReadOnlySpan{byte})"/></returns>
/// <exception cref="Exception"><inheritdoc cref="GetImageFromSpan(System.ReadOnlySpan{byte})"/></exception>
public unsafe static Bitmap GetImageFromSpan(ReadOnlySpan<byte> bytes, out int length)
public unsafe static SKBitmap GetImageFromSpan(ReadOnlySpan<byte> bytes, out int length)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (ubuntu-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (ubuntu-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (ubuntu-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (macOS-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (macOS-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (macOS-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (windows-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (windows-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / publish_cli (windows-latest, Debug, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, true)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, true)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)

Check warning on line 76 in UndertaleModLib/Util/QoiConverter.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, false)

Parameter 'bytes' has no matching param tag in the XML comment for 'QoiConverter.GetImageFromSpan(ReadOnlySpan<byte>, out int)' (but other parameters do)
{
ReadOnlySpan<byte> header = bytes[..12];
if (header[0] != (byte)'f' || header[1] != (byte)'i' || header[2] != (byte)'o' || header[3] != (byte)'q')
Expand All @@ -87,14 +85,12 @@

ReadOnlySpan<byte> pixelData = bytes.Slice(12, length);

Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
bmp.SetResolution(96.0f, 96.0f);

BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
if (data.Stride != width * 4)
SKBitmap bmp = new SKBitmap(width, height);

if (bmp.RowBytes != width * 4)
throw new Exception("Need to reimplement QOI conversions to account for stride, apparently");

byte* bmpPtr = (byte*)data.Scan0;
byte* bmpPtr = (byte*)bmp.GetPixels();
byte* bmpEnd = bmpPtr + (4 * width * height);

int pos = 0;
Expand Down Expand Up @@ -176,30 +172,28 @@
*bmpPtr++ = r;
*bmpPtr++ = a;
}

bmp.UnlockBits(data);


length += header.Length;
return bmp;
}

/// <summary>
/// Creates a QOI image as a byte array from a <see cref="Bitmap"/>.
/// Creates a QOI image as a byte array from a <see cref="SKBitmap"/>.
/// </summary>
/// <param name="bmp">The <see cref="Bitmap"/> to create the QOI image from.</param>
/// <param name="bmp">The <see cref="SKBitmap"/> to create the QOI image from.</param>
/// <param name="padding">The amount of bytes of padding that should be used.</param>
/// <returns>A QOI Image as a byte array.</returns>
/// <exception cref="Exception">If there was an error with stride width.</exception>
public static byte[] GetArrayFromImage(Bitmap bmp, int padding = 4) => GetSpanFromImage(bmp, padding).ToArray();
public static byte[] GetArrayFromImage(SKBitmap bmp, int padding = 4) => GetSpanFromImage(bmp, padding).ToArray();

/// <summary>
/// Creates a QOI image as a <see cref="Span{TKey}"/> from a <see cref="Bitmap"/>.
/// Creates a QOI image as a <see cref="Span{TKey}"/> from a <see cref="SKBitmap"/>.
/// </summary>
/// <param name="bmp">The <see cref="Bitmap"/> to create the QOI image from.</param>
/// <param name="bmp">The <see cref="SKBitmap"/> to create the QOI image from.</param>
/// <param name="padding">The amount of bytes of padding that should be used.</param>
/// <returns>A QOI Image as a byte array.</returns>
/// <exception cref="Exception">If there was an error with stride width.</exception>
public static unsafe Span<byte> GetSpanFromImage(Bitmap bmp, int padding = 4)
public static unsafe Span<byte> GetSpanFromImage(SKBitmap bmp, int padding = 4)
{
if (!isBufferEmpty)
Array.Clear(sharedBuffer);
Expand All @@ -214,11 +208,10 @@
sharedBuffer[6] = (byte)(bmp.Height & 0xff);
sharedBuffer[7] = (byte)((bmp.Height >> 8) & 0xff);

BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
if (data.Stride != bmp.Width * 4)
if (bmp.RowBytes != bmp.Width * 4)
throw new Exception("Need to reimplement QOI conversions to account for stride, apparently");

byte* bmpPtr = (byte*)data.Scan0;
byte* bmpPtr = (byte*)bmp.GetPixels();
byte* bmpEnd = bmpPtr + (4 * bmp.Width * bmp.Height);

int resPos = HeaderSize;
Expand Down Expand Up @@ -310,9 +303,7 @@
vPrev = v;
bmpPtr += 4;
}

bmp.UnlockBits(data);


// Add padding
resPos += padding;

Expand Down
Loading
Loading