mirror of
https://github.com/AssetRipper/AssetRipper.git
synced 2025-12-11 20:15:29 +01:00
Use StbImageWriteSharp instead of System.Drawing.Common
* Resolves #1631
This commit is contained in:
parent
cc95f8a6d8
commit
2132a7113d
@ -19,7 +19,6 @@
|
||||
<PackageReference Include="Kyaru.Texture2DDecoder.macOS" Version="0.1.0" />
|
||||
<PackageReference Include="Kyaru.Texture2DDecoder.Linux" Version="0.1.0" />
|
||||
<PackageReference Include="StbImageWriteSharp" Version="1.16.7" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -19,7 +19,7 @@ public abstract class DirectBitmap
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(height);
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(depth);
|
||||
long byteSize = CalculateByteSize(width, height, depth, PixelSize);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(byteSize, int.MaxValue);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(byteSize, Array.MaxLength);
|
||||
Width = width;
|
||||
Height = height;
|
||||
Depth = depth;
|
||||
@ -47,6 +47,8 @@ public abstract class DirectBitmap
|
||||
}
|
||||
}
|
||||
|
||||
public abstract DirectBitmap GetLayer(int layer);
|
||||
|
||||
public abstract void FlipX();
|
||||
|
||||
public abstract void FlipY();
|
||||
|
||||
@ -2,11 +2,8 @@ using AssetRipper.TextureDecoder.Exr;
|
||||
using AssetRipper.TextureDecoder.Rgb;
|
||||
using AssetRipper.TextureDecoder.Rgb.Formats;
|
||||
using StbImageWriteSharp;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace AssetRipper.Export.Modules.Textures;
|
||||
|
||||
@ -28,6 +25,18 @@ public sealed class DirectBitmap<TColor, TChannel> : DirectBitmap
|
||||
{
|
||||
}
|
||||
|
||||
public override DirectBitmap<TColor, TChannel> GetLayer(int layer)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(layer);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(layer, Depth);
|
||||
|
||||
int layerSize = Width * Height;
|
||||
byte[] layerData = new byte[layerSize * PixelSize];
|
||||
Buffer.BlockCopy(Data, layer * layerSize * PixelSize, layerData, 0, layerSize * PixelSize);
|
||||
|
||||
return new DirectBitmap<TColor, TChannel>(Width, Height, 1, layerData);
|
||||
}
|
||||
|
||||
public override void FlipX()
|
||||
{
|
||||
int totalRows = Height * Depth;
|
||||
@ -89,10 +98,6 @@ public sealed class DirectBitmap<TColor, TChannel> : DirectBitmap
|
||||
{
|
||||
BmpWriter.WriteBmp(Data, Width, Height * Depth, stream);
|
||||
}
|
||||
else if (OperatingSystem.IsWindows())
|
||||
{
|
||||
SaveUsingSystemDrawing(stream, ImageFormat.Bmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
|
||||
@ -119,33 +124,19 @@ public sealed class DirectBitmap<TColor, TChannel> : DirectBitmap
|
||||
|
||||
public override void SaveAsJpeg(Stream stream)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
|
||||
lock (imageWriter)
|
||||
{
|
||||
SaveUsingSystemDrawing(stream, ImageFormat.Jpeg);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
|
||||
lock (imageWriter)
|
||||
{
|
||||
imageWriter.WriteJpg(data, Width, Height * Depth, components, stream, default);
|
||||
}
|
||||
imageWriter.WriteJpg(data, Width, Height * Depth, components, stream, default);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SaveAsPng(Stream stream)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
|
||||
lock (imageWriter)
|
||||
{
|
||||
SaveUsingSystemDrawing(stream, ImageFormat.Png);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
|
||||
lock (imageWriter)
|
||||
{
|
||||
imageWriter.WritePng(data, Width, Height * Depth, components, stream);
|
||||
}
|
||||
imageWriter.WritePng(data, Width, Height * Depth, components, stream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,36 +172,4 @@ public sealed class DirectBitmap<TColor, TChannel> : DirectBitmap
|
||||
components = ColorComponents.RedGreenBlue;
|
||||
}
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private void SaveUsingSystemDrawing(Stream stream, ImageFormat format)
|
||||
{
|
||||
GetData(this, out byte[] data, out int pixelSize, out PixelFormat pixelFormat);
|
||||
GCHandle bitsHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
using Bitmap bitmap = new Bitmap(Width, Height * Depth, Width * pixelSize, pixelFormat, bitsHandle.AddrOfPinnedObject());
|
||||
bitmap.Save(stream, format);
|
||||
}
|
||||
finally
|
||||
{
|
||||
bitsHandle.Free();
|
||||
}
|
||||
|
||||
static void GetData(DirectBitmap<TColor, TChannel> @this, out byte[] data, out int pixelSize, out PixelFormat pixelFormat)
|
||||
{
|
||||
if (typeof(TColor) == typeof(ColorBGRA32))
|
||||
{
|
||||
data = @this.Data;
|
||||
pixelSize = 4;
|
||||
pixelFormat = PixelFormat.Format32bppArgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
RgbConverter.Convert<TColor, TChannel, ColorBGRA32, byte>(@this.Bits, @this.Width, @this.Height * @this.Depth, out data);
|
||||
pixelSize = 4;
|
||||
pixelFormat = PixelFormat.Format32bppArgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ internal sealed class EmptyDirectBitmap : DirectBitmap
|
||||
|
||||
public override int PixelSize => 0;
|
||||
|
||||
public override EmptyDirectBitmap GetLayer(int layer) => this;
|
||||
|
||||
public override void FlipX()
|
||||
{
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user