Untitled
unknown
csharp
2 years ago
3.1 kB
15
Indexable
using System;
using System.Drawing; // Requires System.Drawing.Common package
using System.Drawing.Imaging;
public static Bitmap ResizeImageWithLanczos(Bitmap source, int targetWidth, int targetHeight, int a)
{
Bitmap target = new Bitmap(targetWidth, targetHeight, PixelFormat.Format32bppArgb);
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData targetData = target.LockBits(new Rectangle(0, 0, targetWidth, targetHeight), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int bytesPerPixel = 4; // For Format32bppArgb
byte[] sourceBuffer = new byte[sourceData.Stride * sourceData.Height];
byte[] targetBuffer = new byte[targetData.Stride * targetHeight];
System.Runtime.InteropServices.Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, sourceBuffer.Length);
double scaleX = (double)source.Width / targetWidth;
double scaleY = (double)source.Height / targetHeight;
Parallel.For(0, targetHeight, y =>
{
int targetYOffset = y * targetData.Stride;
for (int x = 0; x < targetWidth; x++)
{
double sourceX = x * scaleX;
double sourceY = y * scaleY;
double sumR = 0, sumG = 0, sumB = 0, sumA = 0, sumWeight = 0;
int xFrom = (int)Math.Max(Math.Floor(sourceX - a), 0);
int xTo = (int)Math.Min(Math.Ceiling(sourceX + a), source.Width - 1);
int yFrom = (int)Math.Max(Math.Floor(sourceY - a), 0);
int yTo = (int)Math.Min(Math.Ceiling(sourceY + a), source.Height - 1);
for (int sy = yFrom; sy <= yTo; sy++)
{
int sourceYOffset = sy * sourceData.Stride;
double dy = LanczosKernel(sourceY - sy, a);
for (int sx = xFrom; sx <= xTo; sx++)
{
double dx = LanczosKernel(sourceX - sx, a);
double weight = dx * dy;
int sourceIndex = sourceYOffset + sx * bytesPerPixel;
sumB += sourceBuffer[sourceIndex] * weight;
sumG += sourceBuffer[sourceIndex + 1] * weight;
sumR += sourceBuffer[sourceIndex + 2] * weight;
sumA += sourceBuffer[sourceIndex + 3] * weight;
sumWeight += weight;
}
}
int targetIndex = targetYOffset + x * bytesPerPixel;
targetBuffer[targetIndex] = ClipToByte(sumB / sumWeight);
targetBuffer[targetIndex + 1] = ClipToByte(sumG / sumWeight);
targetBuffer[targetIndex + 2] = ClipToByte(sumR / sumWeight);
targetBuffer[targetIndex + 3] = ClipToByte(sumA / sumWeight);
}
});
System.Runtime.InteropServices.Marshal.Copy(targetBuffer, 0, targetData.Scan0, targetBuffer.Length);
source.UnlockBits(sourceData);
target.UnlockBits(targetData);
return target;
}
private static byte ClipToByte(double value)
{
return (byte)(Math.Max(Math.Min(value, 255), 0));
}
Editor is loading...
Leave a Comment