我需要对图像中的像素值进行操作。因此我写了这样一堂课:
public class image_class
{
#region property
public int width { get; private set; }
public int height { get; private set; }
byte[] buffer;
#endregion
#region constructors
public image_class()
{
;
}
public image_class(int Width, int Height, byte[] data)
{
if (data.Count() == (Width * Height * 3))
{
this.width = Width;
this.height = Height;
this.buffer = data;
}
else
throw new Exception();
}
#endregion
#region get bitmap
public ImageSource bmp
{
get
{
try
{
var pixelFormat = PixelFormats.Rgb24;
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
var stride = bytesPerPixel * width;
var bitmap = BitmapSource.Create(width, height, 96d, 96d, pixelFormat, null, buffer, stride);
return bitmap;
}
catch { return null; }
}
}
#endregion
#region methods
public void load_from_file(string path)
{
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(ofd.FileName, UriKind.Absolute);
bmp.EndInit();
height = (int)bmp.Height;
width = (int)bmp.Width;
int stride = width * ((bmp.Format.BitsPerPixel + 7) / 8);
int size = height * stride;
var buffer2 = new byte[size];
bmp.CopyPixels(buffer2, stride, 0);
buffer = new byte[size * 3 / 4];
for (int i = 0, j = 0; i < size; i += 4, j += 3)
{
buffer[j] = buffer2[i + 2];
buffer[j + 1] = buffer2[i + 1];
buffer[j + 2] = buffer2[i];
}
}
public void load_from_file(string path, int Width, int Height)
{
this.width = Width;
this.height = Height;
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.DecodePixelHeight = height;
bmp.DecodePixelWidth = width;
bmp.UriSource = new Uri(path, UriKind.Absolute);
bmp.EndInit();
int stride = width * ((bmp.Format.BitsPerPixel + 7) / 8);
int size = height * stride;
var buffer2 = new byte[size];
bmp.CopyPixels(buffer2, stride, 0);
buffer = new byte[size * 3 / 4];
for (int i = 0, j = 0; i < size; i += 4, j += 3)
{
buffer[j] = buffer2[i + 2];
buffer[j + 1] = buffer2[i + 1];
buffer[j + 2] = buffer2[i];
}
}
public void save_to_file(string path)
{
var pixelFormat = PixelFormats.Rgb24;
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
var stride = bytesPerPixel * width;
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(BitmapSource.Create(width, height, 96d, 96d, pixelFormat, null, buffer, stride)));
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
encoder.Save(fs);
fs.Close();
}
public image_class cut(int x0, int y0, int dx, int dy)
{
if (x0 >= 0 & y0 >= 0 & x0 + dx <= width & y0 + dy <= height)
{
byte[] buffer3 = new byte[dx * dy * 3];
for (int y = 0, i = 0, j = -1; y < height; y++) for (int x = 0; x < width; x++, i += 3)
if (x >= x0 & x < x0 + dx & y >= y0 & y < y0 + dy)
{
buffer3[++j] = buffer[i];
buffer3[++j] = buffer[i + 1];
buffer3[++j] = buffer[i + 2];
}
return new image_class(dx, dy, buffer3);
}
else
throw new Exception();
}
#endregion
}
缓冲区数组是我使用的。
这个课程完美无缺。 当我需要处理来自图像片段的数据时,我使用方法剪切,例如:
image_class img1=new image_class();
image_class img2=img1.cut(5,5,20,20);
我需要的是将剪切图像缩放到其他值并保持像素数据的格式。例如,我希望图片中的50x50平方,缩放到20x20。这就是我的工作:
image_class img1=new image_class();
image_class img2=img1.cut(5,5,50,50);
img2.save_to_file(path);
image_class img3=new image_class();
img3.load_from_file(path, 20,20);
它有效,但当然非常无效。有谁能告诉我更好的解决方案?
答案 0 :(得分:2)
你不需要这一切。要从源位图复制矩形部分,然后对其进行缩放,您可以只使用CroppedBitmap
和TransformedBitmap
:
BitmapSource original = ...
var crop = new CroppedBitmap(original, new Int32Rect(5, 5, 50, 50));
var result = new TransformedBitmap(crop, new ScaleTransform(0.4, 0.4));