diff --git a/LibreMetaverse.Rendering.Meshmerizer/LibreMetaverse.Rendering.Meshmerizer.csproj b/LibreMetaverse.Rendering.Meshmerizer/LibreMetaverse.Rendering.Meshmerizer.csproj
index 6cd03aab..07e7e324 100644
--- a/LibreMetaverse.Rendering.Meshmerizer/LibreMetaverse.Rendering.Meshmerizer.csproj
+++ b/LibreMetaverse.Rendering.Meshmerizer/LibreMetaverse.Rendering.Meshmerizer.csproj
@@ -50,7 +50,7 @@
-
+
diff --git a/LibreMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs b/LibreMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs
index 82fbbb85..73f91e58 100644
--- a/LibreMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs
+++ b/LibreMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs
@@ -1,5 +1,5 @@
/* Copyright (c) 2008 Robert Adams
- * Copyright (c) 2021-2022, Sjofn LLC. All rights reserved.
+ * Copyright (c) 2021-2024, Sjofn LLC. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -35,8 +35,8 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
using System.IO;
+using IronSoftware.Drawing;
using OpenMetaverse.StructuredData;
using LibreMetaverse.PrimMesher;
@@ -130,7 +130,7 @@ namespace OpenMetaverse.Rendering
/// Sculpt texture
/// Level of detail to generate the mesh at
/// The generated mesh or null on failure
- public SimpleMesh GenerateSimpleSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod)
+ public SimpleMesh GenerateSimpleSculptMesh(Primitive prim, AnyBitmap sculptTexture, DetailLevel lod)
{
var faceted = GenerateFacetedSculptMesh(prim, sculptTexture, lod);
@@ -225,7 +225,7 @@ namespace OpenMetaverse.Rendering
/// routine since all the context for finding teh texture is elsewhere.
///
/// The faceted mesh or null if can't do it
- public FacetedMesh GenerateFacetedSculptMesh(Primitive prim, Bitmap scupltTexture, DetailLevel lod)
+ public FacetedMesh GenerateFacetedSculptMesh(Primitive prim, AnyBitmap scupltTexture, DetailLevel lod)
{
LibreMetaverse.PrimMesher.SculptMesh.SculptType smSculptType;
switch (prim.Sculpt.Type)
diff --git a/LibreMetaverse.Rendering.Simple/SimpleRenderer.cs b/LibreMetaverse.Rendering.Simple/SimpleRenderer.cs
index e2ff37fe..d5e4284d 100644
--- a/LibreMetaverse.Rendering.Simple/SimpleRenderer.cs
+++ b/LibreMetaverse.Rendering.Simple/SimpleRenderer.cs
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006-2016, openmetaverse.co
+ * Copyright (c) 2024, Sjofn LLC.
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
@@ -24,8 +25,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-using System.Drawing;
using System.Collections.Generic;
+using IronSoftware.Drawing;
namespace OpenMetaverse.Rendering
{
@@ -47,7 +48,7 @@ namespace OpenMetaverse.Rendering
return mesh;
}
- public SimpleMesh GenerateSimpleSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod)
+ public SimpleMesh GenerateSimpleSculptMesh(Primitive prim, AnyBitmap sculptTexture, DetailLevel lod)
{
return GenerateSimpleMesh(prim, lod);
}
@@ -66,7 +67,7 @@ namespace OpenMetaverse.Rendering
return mesh;
}
- public FacetedMesh GenerateFacetedSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod)
+ public FacetedMesh GenerateFacetedSculptMesh(Primitive prim, AnyBitmap sculptTexture, DetailLevel lod)
{
return GenerateFacetedMesh(prim, lod);
}
diff --git a/LibreMetaverse/Imaging/BakeLayer.cs b/LibreMetaverse/Imaging/BakeLayer.cs
index f3778a17..fa27efee 100644
--- a/LibreMetaverse/Imaging/BakeLayer.cs
+++ b/LibreMetaverse/Imaging/BakeLayer.cs
@@ -27,7 +27,7 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Drawing;
+using IronSoftware.Drawing;
using OpenMetaverse.Assets;
namespace OpenMetaverse.Imaging
@@ -356,14 +356,14 @@ namespace OpenMetaverse.Imaging
{
try
{
- Bitmap bitmap = null;
+ AnyBitmap bitmap = null;
lock (ResourceSync)
{
using (Stream stream = Helpers.GetResourceStream(fileName, Settings.RESOURCE_DIR))
{
if (stream != null)
{
- bitmap = LoadTGAClass.LoadTGA(stream);
+ bitmap = SkiaSharp.SKImage.FromEncodedData(stream);
}
}
}
diff --git a/LibreMetaverse/Imaging/ManagedImage.cs b/LibreMetaverse/Imaging/ManagedImage.cs
index 80217ec6..3bd26907 100644
--- a/LibreMetaverse/Imaging/ManagedImage.cs
+++ b/LibreMetaverse/Imaging/ManagedImage.cs
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006-2016, openmetaverse.co
+ * Copyright (c) 2024, Sjofn LLC.
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
@@ -25,8 +26,7 @@
*/
using System;
-using System.Drawing;
-using System.Drawing.Imaging;
+using IronSoftware.Drawing;
namespace OpenMetaverse.Imaging
{
@@ -41,11 +41,6 @@ namespace OpenMetaverse.Imaging
Bump = 8
}
- public enum ImageResizeAlgorithm
- {
- NearestNeighbor
- }
-
///
/// Image width
///
@@ -118,109 +113,70 @@ namespace OpenMetaverse.Imaging
Bump = new byte[n];
}
-#if !NO_UNSAFE
///
- ///
+ /// Constructs ManagedImage class from AnyBitmap
///
- ///
- public ManagedImage(Bitmap bitmap)
+ /// Input AnyBitmap
+ public ManagedImage(AnyBitmap bitmap)
{
Width = bitmap.Width;
Height = bitmap.Height;
+ var pixelCount = Width * Height;
+ var bpp = bitmap.BitsPerPixel;
- int pixelCount = Width * Height;
-
- if (bitmap.PixelFormat == PixelFormat.Format32bppArgb)
+ switch (bpp)
{
- Channels = ImageChannels.Alpha | ImageChannels.Color;
- Red = new byte[pixelCount];
- Green = new byte[pixelCount];
- Blue = new byte[pixelCount];
- Alpha = new byte[pixelCount];
-
- BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, Width, Height),
- ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
-
- unsafe
- {
- byte* pixel = (byte*)bd.Scan0;
-
- for (int i = 0; i < pixelCount; i++)
+ case 32:
+ Channels = ImageChannels.Alpha | ImageChannels.Color;
+ Red = new byte[pixelCount];
+ Green = new byte[pixelCount];
+ Blue = new byte[pixelCount];
+ Alpha = new byte[pixelCount];
+
+ unsafe
{
- // GDI+ gives us BGRA and we need to turn that in to RGBA
- Blue[i] = *(pixel++);
- Green[i] = *(pixel++);
- Red[i] = *(pixel++);
- Alpha[i] = *(pixel++);
+ byte* pixel = (byte*)bitmap.Scan0;
+
+ for (var i = 0; i < pixelCount; ++i)
+ {
+ // GDI+ gives us BGRA and we need to turn that in to RGBA
+ Blue[i] = *pixel++;
+ Green[i] = *pixel++;
+ Red[i] = *pixel++;
+ Alpha[i] = *pixel++;
+ }
}
- }
- bitmap.UnlockBits(bd);
- }
- else if (bitmap.PixelFormat == PixelFormat.Format16bppGrayScale)
- {
- Channels = ImageChannels.Gray;
- Red = new byte[pixelCount];
+ break;
+ case 24:
+ Channels = ImageChannels.Color;
+ Red = new byte[pixelCount];
+ Green = new byte[pixelCount];
+ Blue = new byte[pixelCount];
- throw new NotImplementedException("16bpp grayscale image support is incomplete");
- }
- else if (bitmap.PixelFormat == PixelFormat.Format24bppRgb)
- {
- Channels = ImageChannels.Color;
- Red = new byte[pixelCount];
- Green = new byte[pixelCount];
- Blue = new byte[pixelCount];
-
- BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, Width, Height),
- ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
-
- unsafe
- {
- byte* pixel = (byte*)bd.Scan0;
-
- for (int i = 0; i < pixelCount; i++)
+ unsafe
{
- // GDI+ gives us BGR and we need to turn that in to RGB
- Blue[i] = *(pixel++);
- Green[i] = *(pixel++);
- Red[i] = *(pixel++);
+ byte* pixel = (byte*)bitmap.Scan0;
+
+ for (var i = 0; i < pixelCount; ++i)
+ {
+ // GDI+ gives us BGR and we need to turn that in to RGB
+ Blue[i] = *pixel++;
+ Green[i] = *pixel++;
+ Red[i] = *pixel++;
+ }
}
- }
- bitmap.UnlockBits(bd);
- }
- else if (bitmap.PixelFormat == PixelFormat.Format32bppRgb)
- {
- Channels = ImageChannels.Color;
- Red = new byte[pixelCount];
- Green = new byte[pixelCount];
- Blue = new byte[pixelCount];
-
- BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, Width, Height),
- ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
-
- unsafe
- {
- byte* pixel = (byte*)bd.Scan0;
-
- for (int i = 0; i < pixelCount; i++)
- {
- // GDI+ gives us BGR and we need to turn that in to RGB
- Blue[i] = *(pixel++);
- Green[i] = *(pixel++);
- Red[i] = *(pixel++);
- pixel++; // Skip over the empty byte where the Alpha info would normally be
- }
- }
-
- bitmap.UnlockBits(bd);
- }
- else
- {
- throw new NotSupportedException("Unrecognized pixel format: " + bitmap.PixelFormat);
+ break;
+ case 16:
+ Channels = ImageChannels.Gray;
+ Red = new byte[pixelCount];
+
+ throw new NotImplementedException("16bpp grayscale image support is incomplete");
+ default:
+ throw new NotSupportedException($"Pixel depth of {bpp} is not supported.");
}
}
-#endif
///
/// Convert the channels in the image. Channels are created or destroyed as required.
@@ -293,7 +249,7 @@ namespace OpenMetaverse.Imaging
{
for (int x = 0; x < width; x++)
{
- si = (y * Height / height) * Width + (x * Width / width);
+ si = y * Height / height * Width + x * Width / width;
if (Red != null) red[di] = Red[si];
if (Green != null) green[di] = Green[si];
if (Blue != null) blue[di] = Blue[si];
@@ -384,39 +340,35 @@ namespace OpenMetaverse.Imaging
/// origin, suitable for feeding directly into OpenGL
///
/// A byte array containing raw texture data
- public Bitmap ExportBitmap()
+ public AnyBitmap ExportBitmap()
{
- byte[] raw = new byte[Width * Height * 4];
+ var raw = new byte[Width * Height * 4];
if ((Channels & ImageChannels.Alpha) != 0)
{
if ((Channels & ImageChannels.Color) != 0)
- {
// RGBA
- for (int pos = 0; pos < Height * Width; pos++)
+ for (var pos = 0; pos < Height * Width; pos++)
{
raw[pos * 4 + 0] = Blue[pos];
raw[pos * 4 + 1] = Green[pos];
raw[pos * 4 + 2] = Red[pos];
raw[pos * 4 + 3] = Alpha[pos];
}
- }
else
- {
// Alpha only
- for (int pos = 0; pos < Height * Width; pos++)
+ for (var pos = 0; pos < Height * Width; pos++)
{
raw[pos * 4 + 0] = Alpha[pos];
raw[pos * 4 + 1] = Alpha[pos];
raw[pos * 4 + 2] = Alpha[pos];
raw[pos * 4 + 3] = byte.MaxValue;
}
- }
}
else
{
// RGB
- for (int pos = 0; pos < Height * Width; pos++)
+ for (var pos = 0; pos < Height * Width; pos++)
{
raw[pos * 4 + 0] = Blue[pos];
raw[pos * 4 + 1] = Green[pos];
@@ -425,20 +377,7 @@ namespace OpenMetaverse.Imaging
}
}
- Bitmap b = new Bitmap(
- Width,
- Height,
- PixelFormat.Format32bppArgb);
-
- BitmapData bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
- ImageLockMode.WriteOnly,
- PixelFormat.Format32bppArgb);
-
- System.Runtime.InteropServices.Marshal.Copy(raw, 0, bd.Scan0, Width * Height * 4);
-
- b.UnlockBits(bd);
-
- return b;
+ return AnyBitmap.FromBytes(raw);
}
public byte[] ExportTGA()
diff --git a/LibreMetaverse/Imaging/TGALoader.cs b/LibreMetaverse/Imaging/TGALoader.cs
deleted file mode 100644
index e28046ce..00000000
--- a/LibreMetaverse/Imaging/TGALoader.cs
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * Copyright (c) 2006-2016, openmetaverse.co
- * All rights reserved.
- *
- * - Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * - Neither the name of the openmetaverse.co nor the names
- * of its contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-using System;
-using System.Drawing;
-using System.Drawing.Imaging;
-
-namespace OpenMetaverse.Imaging
-{
-#if !NO_UNSAFE
-
- ///
- /// Capability to load TGAs to Bitmap
- ///
- public class LoadTGAClass
- {
- struct tgaColorMap
- {
- public ushort FirstEntryIndex;
- public ushort Length;
- public byte EntrySize;
-
- public void Read(System.IO.BinaryReader br)
- {
- FirstEntryIndex = br.ReadUInt16();
- Length = br.ReadUInt16();
- EntrySize = br.ReadByte();
- }
- }
-
- struct tgaImageSpec
- {
- public ushort XOrigin;
- public ushort YOrigin;
- public ushort Width;
- public ushort Height;
- public byte PixelDepth;
- public byte Descriptor;
-
- public void Read(System.IO.BinaryReader br)
- {
- XOrigin = br.ReadUInt16();
- YOrigin = br.ReadUInt16();
- Width = br.ReadUInt16();
- Height = br.ReadUInt16();
- PixelDepth = br.ReadByte();
- Descriptor = br.ReadByte();
- }
-
- public byte AlphaBits
- {
- get
- {
- return (byte)(Descriptor & 0xF);
- }
- set
- {
- Descriptor = (byte)((Descriptor & ~0xF) | (value & 0xF));
- }
- }
-
- public bool BottomUp
- {
- get
- {
- return (Descriptor & 0x20) == 0x20;
- }
- set
- {
- Descriptor = (byte)((Descriptor & ~0x20) | (value ? 0x20 : 0));
- }
- }
- }
-
- struct tgaHeader
- {
- public byte IdLength;
- public byte ColorMapType;
- public byte ImageType;
-
- public tgaColorMap ColorMap;
- public tgaImageSpec ImageSpec;
-
- public void Read(System.IO.BinaryReader br)
- {
- this.IdLength = br.ReadByte();
- this.ColorMapType = br.ReadByte();
- this.ImageType = br.ReadByte();
- this.ColorMap = new tgaColorMap();
- this.ImageSpec = new tgaImageSpec();
- this.ColorMap.Read(br);
- this.ImageSpec.Read(br);
- }
-
- public bool RleEncoded
- {
- get
- {
- return ImageType >= 9;
- }
- }
- }
-
- struct tgaCD
- {
- public uint RMask, GMask, BMask, AMask;
- public byte RShift, GShift, BShift, AShift;
- public uint FinalOr;
- public bool NeedNoConvert;
- }
-
- static uint UnpackColor(
- uint sourceColor, ref tgaCD cd)
- {
- if (cd.RMask == 0xFF && cd.GMask == 0xFF && cd.BMask == 0xFF)
- {
- // Special case to deal with 8-bit TGA files that we treat as alpha masks
- return sourceColor << 24;
- }
- else
- {
- uint rpermute = (sourceColor << cd.RShift) | (sourceColor >> (32 - cd.RShift));
- uint gpermute = (sourceColor << cd.GShift) | (sourceColor >> (32 - cd.GShift));
- uint bpermute = (sourceColor << cd.BShift) | (sourceColor >> (32 - cd.BShift));
- uint apermute = (sourceColor << cd.AShift) | (sourceColor >> (32 - cd.AShift));
- uint result =
- (rpermute & cd.RMask) | (gpermute & cd.GMask)
- | (bpermute & cd.BMask) | (apermute & cd.AMask) | cd.FinalOr;
-
- return result;
- }
- }
-
- static unsafe void decodeLine(
- BitmapData b,
- int line,
- int byp,
- byte[] data,
- ref tgaCD cd)
- {
- if (cd.NeedNoConvert)
- {
- // fast copy
- uint* linep = (uint*)((byte*)b.Scan0.ToPointer() + line * b.Stride);
- fixed (byte* ptr = data)
- {
- uint* sptr = (uint*)ptr;
- for (int i = 0; i < b.Width; ++i)
- {
- linep[i] = sptr[i];
- }
- }
- }
- else
- {
- byte* linep = (byte*)b.Scan0.ToPointer() + line * b.Stride;
-
- uint* up = (uint*)linep;
-
- int rdi = 0;
-
- fixed (byte* ptr = data)
- {
- for (int i = 0; i < b.Width; ++i)
- {
- uint x = 0;
- for (int j = 0; j < byp; ++j)
- {
- x |= ((uint)ptr[rdi]) << (j << 3);
- ++rdi;
- }
- up[i] = UnpackColor(x, ref cd);
- }
- }
- }
- }
-
- static void decodeRle(
- BitmapData b,
- int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp)
- {
- try
- {
- int w = b.Width;
- // make buffer larger, so in case of emergency I can decode
- // over line ends.
- byte[] linebuffer = new byte[(w + 128) * byp];
- int maxindex = w * byp;
- int index = 0;
-
- for (int j = 0; j < b.Height; ++j)
- {
- while (index < maxindex)
- {
- byte blocktype = br.ReadByte();
-
- int bytestoread;
- int bytestocopy;
-
- if (blocktype >= 0x80)
- {
- bytestoread = byp;
- bytestocopy = byp * (blocktype - 0x80);
- }
- else
- {
- bytestoread = byp * (blocktype + 1);
- bytestocopy = 0;
- }
-
- //if (index + bytestoread > maxindex)
- // throw new System.ArgumentException ("Corrupt TGA");
-
- br.Read(linebuffer, index, bytestoread);
- index += bytestoread;
-
- for (int i = 0; i != bytestocopy; ++i)
- {
- linebuffer[index + i] = linebuffer[index + i - bytestoread];
- }
- index += bytestocopy;
- }
- if (!bottomUp)
- decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd);
- else
- decodeLine(b, j, byp, linebuffer, ref cd);
-
- if (index > maxindex)
- {
- Array.Copy(linebuffer, maxindex, linebuffer, 0, index - maxindex);
- index -= maxindex;
- }
- else
- index = 0;
-
- }
- }
- catch (System.IO.EndOfStreamException)
- {
- }
- }
-
- static void decodePlain(
- BitmapData b,
- int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp)
- {
- int w = b.Width;
- byte[] linebuffer = new byte[w * byp];
-
- for (int j = 0; j < b.Height; ++j)
- {
- br.Read(linebuffer, 0, w * byp);
-
- if (!bottomUp)
- decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd);
- else
- decodeLine(b, j, byp, linebuffer, ref cd);
- }
- }
-
- static void decodeStandard8(
- BitmapData b,
- tgaHeader hdr,
- System.IO.BinaryReader br)
- {
- tgaCD cd = new tgaCD();
- cd.RMask = 0x000000ff;
- cd.GMask = 0x000000ff;
- cd.BMask = 0x000000ff;
- cd.AMask = 0x000000ff;
- cd.RShift = 0;
- cd.GShift = 0;
- cd.BShift = 0;
- cd.AShift = 0;
- cd.FinalOr = 0x00000000;
- if (hdr.RleEncoded)
- decodeRle(b, 1, cd, br, hdr.ImageSpec.BottomUp);
- else
- decodePlain(b, 1, cd, br, hdr.ImageSpec.BottomUp);
- }
-
- static void decodeSpecial16(
- BitmapData b, tgaHeader hdr, System.IO.BinaryReader br)
- {
- // i must convert the input stream to a sequence of uint values
- // which I then unpack.
- tgaCD cd = new tgaCD();
- cd.RMask = 0x00f00000;
- cd.GMask = 0x0000f000;
- cd.BMask = 0x000000f0;
- cd.AMask = 0xf0000000;
- cd.RShift = 12;
- cd.GShift = 8;
- cd.BShift = 4;
- cd.AShift = 16;
- cd.FinalOr = 0;
-
- if (hdr.RleEncoded)
- decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp);
- else
- decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp);
- }
-
- static void decodeStandard16(
- BitmapData b,
- tgaHeader hdr,
- System.IO.BinaryReader br)
- {
- // i must convert the input stream to a sequence of uint values
- // which I then unpack.
- tgaCD cd = new tgaCD();
- cd.RMask = 0x00f80000; // from 0xF800
- cd.GMask = 0x0000fc00; // from 0x07E0
- cd.BMask = 0x000000f8; // from 0x001F
- cd.AMask = 0x00000000;
- cd.RShift = 8;
- cd.GShift = 5;
- cd.BShift = 3;
- cd.AShift = 0;
- cd.FinalOr = 0xff000000;
-
- if (hdr.RleEncoded)
- decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp);
- else
- decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp);
- }
-
-
- static void decodeSpecial24(BitmapData b,
- tgaHeader hdr, System.IO.BinaryReader br)
- {
- // i must convert the input stream to a sequence of uint values
- // which I then unpack.
- tgaCD cd = new tgaCD();
- cd.RMask = 0x00f80000;
- cd.GMask = 0x0000fc00;
- cd.BMask = 0x000000f8;
- cd.AMask = 0xff000000;
- cd.RShift = 8;
- cd.GShift = 5;
- cd.BShift = 3;
- cd.AShift = 8;
- cd.FinalOr = 0;
-
- if (hdr.RleEncoded)
- decodeRle(b, 3, cd, br, hdr.ImageSpec.BottomUp);
- else
- decodePlain(b, 3, cd, br, hdr.ImageSpec.BottomUp);
- }
-
- static void decodeStandard24(BitmapData b,
- tgaHeader hdr, System.IO.BinaryReader br)
- {
- // i must convert the input stream to a sequence of uint values
- // which I then unpack.
- tgaCD cd = new tgaCD();
- cd.RMask = 0x00ff0000;
- cd.GMask = 0x0000ff00;
- cd.BMask = 0x000000ff;
- cd.AMask = 0x00000000;
- cd.RShift = 0;
- cd.GShift = 0;
- cd.BShift = 0;
- cd.AShift = 0;
- cd.FinalOr = 0xff000000;
-
- if (hdr.RleEncoded)
- decodeRle(b, 3, cd, br, hdr.ImageSpec.BottomUp);
- else
- decodePlain(b, 3, cd, br, hdr.ImageSpec.BottomUp);
- }
-
- static void decodeStandard32(BitmapData b,
- tgaHeader hdr, System.IO.BinaryReader br)
- {
- // i must convert the input stream to a sequence of uint values
- // which I then unpack.
- tgaCD cd = new tgaCD();
- cd.RMask = 0x00ff0000;
- cd.GMask = 0x0000ff00;
- cd.BMask = 0x000000ff;
- cd.AMask = 0xff000000;
- cd.RShift = 0;
- cd.GShift = 0;
- cd.BShift = 0;
- cd.AShift = 0;
- cd.FinalOr = 0x00000000;
- cd.NeedNoConvert = true;
-
- if (hdr.RleEncoded)
- decodeRle(b, 4, cd, br, hdr.ImageSpec.BottomUp);
- else
- decodePlain(b, 4, cd, br, hdr.ImageSpec.BottomUp);
- }
-
-
- public static System.Drawing.Size GetTGASize(string filename)
- {
- System.IO.FileStream f = System.IO.File.OpenRead(filename);
-
- System.IO.BinaryReader br = new System.IO.BinaryReader(f);
-
- tgaHeader header = new tgaHeader();
- header.Read(br);
- br.Close();
-
- return new System.Drawing.Size(header.ImageSpec.Width, header.ImageSpec.Height);
-
- }
-
- public static Bitmap LoadTGA(System.IO.Stream source)
- {
- byte[] buffer = new byte[source.Length];
- source.Read(buffer, 0, buffer.Length);
-
- System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
-
- using (System.IO.BinaryReader br = new System.IO.BinaryReader(ms))
- {
- tgaHeader header = new tgaHeader();
- header.Read(br);
-
- if (header.ImageSpec.PixelDepth != 8 &&
- header.ImageSpec.PixelDepth != 16 &&
- header.ImageSpec.PixelDepth != 24 &&
- header.ImageSpec.PixelDepth != 32)
- {
- throw new ArgumentException("Not a supported tga file.");
- }
-
- if (header.ImageSpec.AlphaBits > 8)
- throw new ArgumentException("Not a supported tga file.");
-
- if (header.ImageSpec.Width > 4096 ||
- header.ImageSpec.Height > 4096)
- {
- throw new ArgumentException("Image too large.");
- }
-
- Bitmap b;
- BitmapData bd;
-
- // Create a bitmap for the image.
- // Only include an alpha layer when the image requires one.
- if (header.ImageSpec.AlphaBits > 0 ||
- header.ImageSpec.PixelDepth == 8 || // Assume 8 bit images are alpha only
- header.ImageSpec.PixelDepth == 32) // Assume 32 bit images are ARGB
- { // Image needs an alpha layer
- b = new Bitmap(
- header.ImageSpec.Width,
- header.ImageSpec.Height,
- PixelFormat.Format32bppArgb);
-
- bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
- ImageLockMode.WriteOnly,
- PixelFormat.Format32bppPArgb);
- }
- else
- { // Image does not need an alpha layer, so do not include one.
- b = new Bitmap(
- header.ImageSpec.Width,
- header.ImageSpec.Height,
- PixelFormat.Format32bppRgb);
-
- bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
- ImageLockMode.WriteOnly,
- PixelFormat.Format32bppRgb);
- }
-
- switch (header.ImageSpec.PixelDepth)
- {
- case 8:
- decodeStandard8(bd, header, br);
- break;
- case 16:
- if (header.ImageSpec.AlphaBits > 0)
- decodeSpecial16(bd, header, br);
- else
- decodeStandard16(bd, header, br);
- break;
- case 24:
- if (header.ImageSpec.AlphaBits > 0)
- decodeSpecial24(bd, header, br);
- else
- decodeStandard24(bd, header, br);
- break;
- case 32:
- decodeStandard32(bd, header, br);
- break;
- default:
- b.UnlockBits(bd);
- b.Dispose();
- return null;
- }
-
- b.UnlockBits(bd);
- return b;
- }
- }
-
- public static ManagedImage LoadTGAImage(System.IO.Stream source)
- {
- return LoadTGAImage(source, false);
- }
-
- public static unsafe ManagedImage LoadTGAImage(System.IO.Stream source, bool mask)
- {
- byte[] buffer = new byte[source.Length];
- source.Read(buffer, 0, buffer.Length);
-
- System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
-
- using (System.IO.BinaryReader br = new System.IO.BinaryReader(ms))
- {
- tgaHeader header = new tgaHeader();
- header.Read(br);
-
- if (header.ImageSpec.PixelDepth != 8 &&
- header.ImageSpec.PixelDepth != 16 &&
- header.ImageSpec.PixelDepth != 24 &&
- header.ImageSpec.PixelDepth != 32)
- {
- throw new ArgumentException("Not a supported tga file.");
- }
-
- if (header.ImageSpec.AlphaBits > 8)
- throw new ArgumentException("Not a supported tga file.");
-
- if (header.ImageSpec.Width > 4096 ||
- header.ImageSpec.Height > 4096)
- {
- throw new ArgumentException("Image too large.");
- }
-
- byte[] decoded = new byte[header.ImageSpec.Width * header.ImageSpec.Height * 4];
- BitmapData bd = new BitmapData();
-
- fixed (byte* pdecoded = &decoded[0])
- {
- bd.Width = header.ImageSpec.Width;
- bd.Height = header.ImageSpec.Height;
- bd.PixelFormat = PixelFormat.Format32bppPArgb;
- bd.Stride = header.ImageSpec.Width * 4;
- bd.Scan0 = (IntPtr)pdecoded;
-
- switch (header.ImageSpec.PixelDepth)
- {
- case 8:
- decodeStandard8(bd, header, br);
- break;
- case 16:
- if (header.ImageSpec.AlphaBits > 0)
- decodeSpecial16(bd, header, br);
- else
- decodeStandard16(bd, header, br);
- break;
- case 24:
- if (header.ImageSpec.AlphaBits > 0)
- decodeSpecial24(bd, header, br);
- else
- decodeStandard24(bd, header, br);
- break;
- case 32:
- decodeStandard32(bd, header, br);
- break;
- default:
- return null;
- }
- }
-
- int n = header.ImageSpec.Width * header.ImageSpec.Height;
- ManagedImage image;
-
- if (mask && header.ImageSpec.AlphaBits == 0 && header.ImageSpec.PixelDepth == 8)
- {
- image = new ManagedImage(header.ImageSpec.Width, header.ImageSpec.Height,
- ManagedImage.ImageChannels.Alpha);
- int p = 3;
-
- for (int i = 0; i < n; i++)
- {
- image.Alpha[i] = decoded[p];
- p += 4;
- }
- }
- else
- {
- image = new ManagedImage(header.ImageSpec.Width, header.ImageSpec.Height,
- ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha);
- int p = 0;
-
- for (int i = 0; i < n; i++)
- {
- image.Blue[i] = decoded[p++];
- image.Green[i] = decoded[p++];
- image.Red[i] = decoded[p++];
- image.Alpha[i] = decoded[p++];
- }
- }
-
- br.Close();
- return image;
- }
- }
-
- public static Bitmap LoadTGA(string filename)
- {
- try
- {
- using (System.IO.FileStream f = System.IO.File.OpenRead(filename))
- {
- if (f != null)
- {
- return LoadTGA(f);
- }
- }
- return null; // file stream error
- }
- catch (System.IO.DirectoryNotFoundException)
- {
- return null; // file not found
- }
- catch (System.IO.FileNotFoundException)
- {
- return null; // file not found
- }
- }
- }
-
-#endif
-}
diff --git a/LibreMetaverse/ImportExport/ColladalLoader.cs b/LibreMetaverse/ImportExport/ColladalLoader.cs
index cac6fe66..b96b566f 100644
--- a/LibreMetaverse/ImportExport/ColladalLoader.cs
+++ b/LibreMetaverse/ImportExport/ColladalLoader.cs
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2006-2016, openmetaverse.co
- * Copyright (c) 2021-2022, Sjofn LLC.
+ * Copyright (c) 2021-2024, Sjofn LLC.
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
@@ -31,13 +31,13 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml;
-using System.Drawing;
-using System.Drawing.Drawing2D;
using System.Linq;
using System.Xml.Serialization;
+using IronSoftware.Drawing;
using OpenMetaverse.ImportExport.Collada14;
using OpenMetaverse.Rendering;
using OpenMetaverse.Imaging;
+using SkiaSharp;
namespace OpenMetaverse.ImportExport
{
@@ -120,7 +120,7 @@ namespace OpenMetaverse.ImportExport
{
string ext = System.IO.Path.GetExtension(material.Texture).ToLower();
- Bitmap bitmap = null;
+ AnyBitmap bitmap;
switch (ext)
{
@@ -128,11 +128,8 @@ namespace OpenMetaverse.ImportExport
case ".j2c":
material.TextureData = File.ReadAllBytes(fname);
return;
- case ".tga":
- bitmap = LoadTGAClass.LoadTGA(fname);
- break;
default:
- bitmap = (Bitmap)Image.FromFile(fname);
+ bitmap = AnyBitmap.FromFile(fname);
break;
}
@@ -153,16 +150,11 @@ namespace OpenMetaverse.ImportExport
Logger.Log("Image has irregular dimensions " + origWidth + "x" + origHieght + ". Resizing to " + width + "x" + height, Helpers.LogLevel.Info);
- Bitmap resized = new Bitmap(width, height, bitmap.PixelFormat);
- Graphics graphics = Graphics.FromImage(resized);
-
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.InterpolationMode =
- InterpolationMode.HighQualityBicubic;
- graphics.DrawImage(bitmap, 0, 0, width, height);
-
- bitmap.Dispose();
- bitmap = resized;
+ var info = new SKImageInfo(width, height);
+ var scaledImage = SKImage.Create(info);
+ var skImage = SKImage.FromBitmap(bitmap);
+ skImage.ScalePixels(scaledImage.PeekPixels(), SKFilterQuality.High);
+ bitmap = scaledImage;
}
using (var writer = new OpenJpegDotNet.IO.Writer(bitmap))
@@ -174,7 +166,7 @@ namespace OpenMetaverse.ImportExport
}
catch (Exception ex)
{
- Logger.Log("Failed loading " + fname + ": " + ex.Message, Helpers.LogLevel.Warning);
+ Logger.Log($"Failed loading {fname}: {ex.Message}", Helpers.LogLevel.Warning);
}
}
diff --git a/LibreMetaverse/Interfaces/IRendering.cs b/LibreMetaverse/Interfaces/IRendering.cs
index d0a916db..14e5f2a5 100644
--- a/LibreMetaverse/Interfaces/IRendering.cs
+++ b/LibreMetaverse/Interfaces/IRendering.cs
@@ -26,7 +26,7 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
+using IronSoftware.Drawing;
namespace OpenMetaverse.Rendering
{
@@ -67,7 +67,7 @@ namespace OpenMetaverse.Rendering
/// Sculpt texture
/// Level of detail to generate the mesh at
/// The generated mesh
- SimpleMesh GenerateSimpleSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod);
+ SimpleMesh GenerateSimpleSculptMesh(Primitive prim, AnyBitmap sculptTexture, DetailLevel lod);
///
/// Generates a series of faces, each face containing a mesh and
@@ -86,7 +86,7 @@ namespace OpenMetaverse.Rendering
/// Sculpt texture
/// Level of detail to generate the mesh at
/// The generated mesh
- FacetedMesh GenerateFacetedSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod);
+ FacetedMesh GenerateFacetedSculptMesh(Primitive prim, AnyBitmap sculptTexture, DetailLevel lod);
///
/// Apply texture coordinate modifications from a
diff --git a/LibreMetaverse/LibreMetaverse.csproj b/LibreMetaverse/LibreMetaverse.csproj
index 6412b94b..5f892ef5 100644
--- a/LibreMetaverse/LibreMetaverse.csproj
+++ b/LibreMetaverse/LibreMetaverse.csproj
@@ -43,11 +43,13 @@
True
+
-
-
+
+
+
diff --git a/PrimMesher/LibreMetaverse.PrimMesher.csproj b/PrimMesher/LibreMetaverse.PrimMesher.csproj
index 268da745..a6e94ed0 100644
--- a/PrimMesher/LibreMetaverse.PrimMesher.csproj
+++ b/PrimMesher/LibreMetaverse.PrimMesher.csproj
@@ -46,12 +46,14 @@
true
TRACE;VERTEX_INDEXER
-
-
-
+
+
+
+
+
diff --git a/PrimMesher/SculptMap.cs b/PrimMesher/SculptMap.cs
index 3c52cebb..101c168f 100644
--- a/PrimMesher/SculptMap.cs
+++ b/PrimMesher/SculptMap.cs
@@ -27,8 +27,8 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Drawing2D;
+using IronSoftware.Drawing;
+using SkiaSharp;
namespace LibreMetaverse.PrimMesher
{
@@ -44,7 +44,7 @@ namespace LibreMetaverse.PrimMesher
{
}
- public SculptMap(Bitmap bm, int lod)
+ public SculptMap(AnyBitmap bm, int lod)
{
var bmW = bm.Width;
var bmH = bm.Height;
@@ -71,8 +71,7 @@ namespace LibreMetaverse.PrimMesher
try
{
if (needsScaling)
- bm = ScaleImage(bm, width, height,
- InterpolationMode.NearestNeighbor);
+ bm = ScaleImage(bm, width, height);
}
catch (Exception e)
@@ -164,21 +163,12 @@ namespace LibreMetaverse.PrimMesher
return rows;
}
- private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
- InterpolationMode interpMode)
+ private AnyBitmap ScaleImage(AnyBitmap srcImage, int destWidth, int destHeight)
{
- var scaledImage = new Bitmap(srcImage, destWidth, destHeight);
- scaledImage.SetResolution(96.0f, 96.0f);
-
- var grPhoto = Graphics.FromImage(scaledImage);
- grPhoto.InterpolationMode = interpMode;
-
- grPhoto.DrawImage(srcImage,
- new Rectangle(0, 0, destWidth, destHeight),
- new Rectangle(0, 0, srcImage.Width, srcImage.Height),
- GraphicsUnit.Pixel);
-
- grPhoto.Dispose();
+ var info = new SKImageInfo(destWidth, destHeight);
+ var scaledImage = SKImage.Create(info);
+ var skImage = SKImage.FromBitmap(srcImage);
+ skImage.ScalePixels(scaledImage.PeekPixels(), SKFilterQuality.High);
return scaledImage;
}
}
diff --git a/PrimMesher/SculptMesh.cs b/PrimMesher/SculptMesh.cs
index 00b31d6e..132f3b1a 100644
--- a/PrimMesher/SculptMesh.cs
+++ b/PrimMesher/SculptMesh.cs
@@ -27,8 +27,9 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
using System.IO;
+using IronSoftware.Drawing;
+using Color = IronSoftware.Drawing.Color;
namespace LibreMetaverse.PrimMesher
{
@@ -52,7 +53,7 @@ namespace LibreMetaverse.PrimMesher
public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert)
{
- var bitmap = (Bitmap) Image.FromFile(fileName);
+ var bitmap = AnyBitmap.FromFile(fileName);
_SculptMesh(bitmap, (SculptType) sculptType, lod, viewerMode != 0, mirror != 0, invert != 0);
bitmap.Dispose();
}
@@ -164,12 +165,12 @@ namespace LibreMetaverse.PrimMesher
calcVertexNormals(SculptType.plane, numXElements, numYElements);
}
- public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
+ public SculptMesh(AnyBitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
{
_SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false);
}
- public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror,
+ public SculptMesh(AnyBitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror,
bool invert)
{
_SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert);
@@ -191,7 +192,7 @@ namespace LibreMetaverse.PrimMesher
public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
{
- var bitmap = (Bitmap) Image.FromFile(fileName);
+ var bitmap = AnyBitmap.FromFile(fileName);
var sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode);
bitmap.Dispose();
return sculptMesh;
@@ -207,7 +208,7 @@ namespace LibreMetaverse.PrimMesher
///
///
///
- private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror)
+ private List> bitmap2Coords(AnyBitmap bitmap, int scale, bool mirror)
{
var numRows = bitmap.Height / scale;
var numCols = bitmap.Width / scale;
@@ -254,7 +255,7 @@ namespace LibreMetaverse.PrimMesher
return rows;
}
- private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror)
+ private List> bitmap2CoordsSampled(AnyBitmap bitmap, int scale, bool mirror)
{
var numRows = bitmap.Height / scale;
var numCols = bitmap.Width / scale;
@@ -293,7 +294,7 @@ namespace LibreMetaverse.PrimMesher
}
- private void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror,
+ private void _SculptMesh(AnyBitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror,
bool invert)
{
_SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert);
diff --git a/Programs/Baker/Oven.cs b/Programs/Baker/Oven.cs
index 00028e05..7e76fc89 100644
--- a/Programs/Baker/Oven.cs
+++ b/Programs/Baker/Oven.cs
@@ -1,5 +1,4 @@
using System;
-using System.Drawing;
using System.Runtime.InteropServices;
namespace Baker
diff --git a/Programs/Baker/frmBaker.cs b/Programs/Baker/frmBaker.cs
index 2afeedb0..2ddcc708 100644
--- a/Programs/Baker/frmBaker.cs
+++ b/Programs/Baker/frmBaker.cs
@@ -1,5 +1,4 @@
using System;
-using System.Drawing;
using System.Windows.Forms;
using System.IO;
using OpenMetaverse.Imaging;
diff --git a/Programs/examples/GridAccountant/frmGridAccountant.cs b/Programs/examples/GridAccountant/frmGridAccountant.cs
index 3581c872..da597fb7 100644
--- a/Programs/examples/GridAccountant/frmGridAccountant.cs
+++ b/Programs/examples/GridAccountant/frmGridAccountant.cs
@@ -25,7 +25,6 @@
*/
using System;
-using System.Drawing;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
diff --git a/Programs/examples/TestClient/Commands/Inventory/UploadImageCommand.cs b/Programs/examples/TestClient/Commands/Inventory/UploadImageCommand.cs
index 6f3855c2..36a5e403 100644
--- a/Programs/examples/TestClient/Commands/Inventory/UploadImageCommand.cs
+++ b/Programs/examples/TestClient/Commands/Inventory/UploadImageCommand.cs
@@ -27,9 +27,8 @@
using System;
using System.Threading;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using OpenMetaverse.Imaging;
+using IronSoftware.Drawing;
+using SkiaSharp;
namespace OpenMetaverse.TestClient
{
@@ -96,18 +95,18 @@ namespace OpenMetaverse.TestClient
private byte[] LoadImage(string fileName)
{
- byte[] UploadData = { };
+ byte[] uploadData;
string lowfilename = fileName.ToLower();
- Bitmap bitmap = null;
try
{
+ AnyBitmap bitmap;
if (lowfilename.EndsWith(".jp2") || lowfilename.EndsWith(".j2c"))
{
// Upload JPEG2000 images untouched
- UploadData = System.IO.File.ReadAllBytes(fileName);
+ uploadData = System.IO.File.ReadAllBytes(fileName);
- using (var reader = new OpenJpegDotNet.IO.Reader(UploadData))
+ using (var reader = new OpenJpegDotNet.IO.Reader(uploadData))
{
reader.ReadHeader();
bitmap = reader.DecodeToBitmap();
@@ -115,25 +114,18 @@ namespace OpenMetaverse.TestClient
}
else
{
- if (lowfilename.EndsWith(".tga")) {
- bitmap = LoadTGAClass.LoadTGA(fileName);
- } else {
- bitmap = (Bitmap)Image.FromFile(fileName);
- }
+ bitmap = AnyBitmap.FromFile(fileName);
int oldwidth = bitmap.Width;
int oldheight = bitmap.Height;
if (!IsPowerOfTwo((uint)oldwidth) || !IsPowerOfTwo((uint)oldheight))
{
- Bitmap resized = new Bitmap(256, 256, bitmap.PixelFormat);
- Graphics graphics = Graphics.FromImage(resized);
+ var info = new SKImageInfo(256, 256);
+ var scaledImage = SKImage.Create(info);
+ var skImage = SKImage.FromBitmap(bitmap);
+ skImage.ScalePixels(scaledImage.PeekPixels(), SKFilterQuality.High);
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.DrawImage(bitmap, 0, 0, 256, 256);
-
- bitmap.Dispose();
- bitmap = resized;
+ bitmap = scaledImage;
oldwidth = 256;
oldheight = 256;
@@ -145,21 +137,18 @@ namespace OpenMetaverse.TestClient
int newwidth = (oldwidth > 1024) ? 1024 : oldwidth;
int newheight = (oldheight > 1024) ? 1024 : oldheight;
- Bitmap resized = new Bitmap(newwidth, newheight, bitmap.PixelFormat);
- Graphics graphics = Graphics.FromImage(resized);
+ var info = new SKImageInfo(newwidth, newheight);
+ var scaledImage = SKImage.Create(info);
+ var skImage = SKImage.FromBitmap(bitmap);
+ skImage.ScalePixels(scaledImage.PeekPixels(), SKFilterQuality.High);
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.InterpolationMode =
- InterpolationMode.HighQualityBicubic;
- graphics.DrawImage(bitmap, 0, 0, newwidth, newheight);
+ bitmap = scaledImage;
+ }
+ }
- bitmap.Dispose();
- bitmap = resized;
- }
- using (var writer = new OpenJpegDotNet.IO.Writer(bitmap))
- {
- UploadData = writer.Encode();
- }
+ using (var writer = new OpenJpegDotNet.IO.Writer(bitmap))
+ {
+ uploadData = writer.Encode();
}
}
catch (Exception ex)
@@ -167,7 +156,7 @@ namespace OpenMetaverse.TestClient
Console.WriteLine(ex + " SL Image Upload ");
return null;
}
- return UploadData;
+ return uploadData;
}
private static bool IsPowerOfTwo(uint n)