65.9K
CodeProject 正在变化。 阅读更多。
Home

保持纵横比的简单图像编辑器(裁剪和缩放)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (26投票s)

2008年12月28日

CPOL

1分钟阅读

viewsIcon

109217

downloadIcon

14780

CodeProject 想法的融合。

CropResizeSrc

引言

我正在开发一个需要将图像添加到数据库的项目。 大多数图像来自800万像素的数码相机,因此尺寸相当大。 最初,我只是按比例将图像调整为1024 x 768,然后就完成了。 但我担心有些图像包含忙碌的背景或干扰物,可以裁剪掉。 这个项目是我努力的结果。

背景 

请注意,我并不声称我编写了该项目的大部分代码。 我站在巨人的肩膀上,从许多不同的CodeProject文章中学习和重用了代码。 希望整体大于部分之和。 本文基于ImageResizer.aspx和各种CodeProject文章中的代码。

使用代码 

源代码应该相当容易理解。

关键在于保持所有纵横比正确。

private static Image CropImage(Image img, Rectangle cropArea)
{
    try {
	Bitmap bmpImage = new Bitmap(img);
	Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
	return (Image)(bmpCrop);
    }
    catch (Exception ex)
    {
	MessageBox.Show(ex.Message, "CropImage()");
    }
    return null;
}

private void saveJpeg(string path, Bitmap img, long quality)
{
    // Encoder parameter for image quality
    EncoderParameter qualityParam = new EncoderParameter(
    System.Drawing.Imaging.Encoder.Quality, (long)quality);

    // Jpeg image codec
    ImageCodecInfo jpegCodec = getEncoderInfo("image/jpeg");

    if (jpegCodec == null)
    {
	MessageBox.Show("Can't find JPEG encoder?", "saveJpeg()");
	return;
    }
    EncoderParameters encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = qualityParam;
  
    img.Save(path, jpegCodec, encoderParams);
}

private ImageCodecInfo getEncoderInfo(string mimeType)
{
    // Get image codecs for all image formats
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

    // Find the correct image codec
    for (int i = 0; i < codecs.Length; i++)
	if (codecs[i].MimeType == mimeType)
   	   return codecs[i];

    return null;
}

private void btnOK_Click(object sender, EventArgs e)
{
    // output image size is based upon the visible crop rectangle and scaled to 
    // the ratio of actual image size to displayed image size
    Bitmap bmp = null;

    Rectangle ScaledCropRect = new Rectangle();
    ScaledCropRect.X         = (int)(CropRect.X / ZoomedRatio);
    ScaledCropRect.Y         = (int)(CropRect.Y / ZoomedRatio);
    ScaledCropRect.Width     = (int)((double)(CropRect.Width) / ZoomedRatio);
    ScaledCropRect.Height    = (int)((double)(CropRect.Height) / ZoomedRatio);

    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
    {
	try
	{
       bmp = (Bitmap)CropImage(pictureBox1.Image, ScaledCropRect);
	   // 85% quality
	   saveJpeg(saveFileDialog1.FileName, bmp, 85);
	}
	catch(Exception ex)
	{
	   MessageBox.Show(ex.Message, "btnOK_Click()");
	}
    }

    if(bmp != null)
         bmp.Dispose();
}

兴趣点 

有一个透明的裁剪框,可以通过其角拖动,或通过左键单击并移动来移动。 裁剪框的纵横比由组合框中的值决定。 另一个组合框只是设置裁剪框的宽度,高度由所选的纵横比确定。 调整裁剪框大小时,它将自动对齐到比例纵横比。

有一些简单的图像处理功能可用;旋转、反色、灰度、对比度和亮度。

注意:我的所有图像都是横向的,因此我没有在代码中花时间处理纵向模式调整大小的情况。

历史

  • 2008年12月28日:初始发布
  • 2008年12月30日:更新了更正后的代码
© . All rights reserved.