非完美主义者
2017-12-12 10:20
采纳率: 40%
浏览 1.6k

C#缩放图片后,左边缘颜色失真的问题

各位大侠,我使用C#来缩放图片后,图片左边缘总是有颜色失真的问题,尝试了一天没有能够解决,请各位帮忙看看问题在哪儿?谢谢。
图片如下(放大了截的图,失真看得比较明显):
原始图纯蓝
缩放后左边缘颜色失真

代码是这样的:

 public Image MatchCanvas(Image srcImage, float widthSize, float heightSize)
{
    float INCH_PER_MM = 0.0393701F; // 1毫米0.0393701英寸,因为传入的目标widthSize和heightSize是以毫米为单位的。

    // 目标图片像素,输入是mm,转换成inch,再乘以分辨率,输入是mm,转换成inch,再乘以分辨率
    int dstWidth = Convert.ToInt32(widthSize * PdfVariable.INCH_PER_MM * srcImage.HorizontalResolution);
    int dstHeight = Convert.ToInt32(heightSize * PdfVariable.INCH_PER_MM * srcImage.VerticalResolution);

    // 原始图片像素
    int srcWidth = srcImage.Width;
    int srcHeight = srcImage.Height;

    // new一个Bitmap就是目标图片
    Bitmap newImage = new Bitmap(dstWidth, dstHeight);
    newImage.SetResolution(srcImage.HorizontalResolution, srcImage.VerticalResolution);

    Graphics g4Image = Graphics.FromImage(newImage);

    // 设置图片质量
    g4Image.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g4Image.SmoothingMode = SmoothingMode.HighQuality;
    g4Image.Clear(Color.White);

    /* 根据对齐方式设置各项偏移量
     * srcWidthOff 和 srcHeightOff 是源图片偏移量,如果源图片尺寸大于画布,则需要偏移
     * dstWidthOff 和 dstHeightOff 是画布偏移量,如果源图片尺寸小于画布,则需要偏移
     * widthRage 和 heightRange 是指作画的长宽 */
    int srcWidthOff = 0, srcHeightOff = 0, dstWidthOff = 0, dstHeightOff = 0;
    int widthRange = 0, heightRange = 0;
    int srcWidthRange = 0, srcHeightRange = 0, dstWidthRange = 0, dstHeightRange = 0;

    // 底边为准等比缩放
    // 以width为准对齐,先算出缩放比例,然后再看hight,等比例缩放后,有两种情况:
    // 1,不够显示,原图片中上下裁剪相同尺寸
    // 2,足够显示,原图片Y轴居中放置
    srcWidthRange = srcWidth;
    dstWidthRange = dstWidth;

    int needHeight = (int)(srcHeight * (float)((float)dstWidth / (float)srcWidth));
    if (needHeight < dstHeight)
    {
        // 足够显示
        srcHeightRange = srcHeight;
        dstHeightOff = (dstHeight - needHeight) / 2; 
        dstHeightRange = needHeight;
    }
    else
    {
        // 不够显示 capHeight是能够显示的原始图片像素数
        int capHeight = (int)(dstHeight * (float)((float)srcWidth / (float)dstWidth));
        srcHeightOff = (srcHeight - capHeight) / 2;
        srcHeightRange = capHeight;
        dstHeightRange = dstHeight;
    }

    rectangle srcRect = new Rectangle(srcWidthOff, srcHeightOff, srcWidthRange, srcHeightRange);
    Rectangle dstRect = new Rectangle(dstWidthOff, dstHeightOff, dstWidthRange, dstHeightRange);

    try
    {
        g4Image.DrawImage(srcImage, dstRect, srcRect, System.Drawing.GraphicsUnit.Pixel);
    }
    catch (ArgumentException ex)
    {
        Trace.TraceError(ex.Message);
    }
    finally
    {
        g4Image.Dispose();
    }

    return newImage;
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • tokaikaibbs 2017-12-12 13:48
    已采纳

    之前用过多种方法,包括很多第三方类库,发现哪个也不如photoshop压缩得好,而且放大后仔细对比都差不少,PS真不亏是行业老大,后来更换了思路用c#调用ps类库,用ps接口实现图片的压缩和保存,堪称完美!
    这样做最大的缺点就是需要装ps软件而且还要长期保持运行,而且也比较慢,但效果真的碾压所谓的各种无损压缩,刚好我的项目对质量非常高,效率可以适当做出牺牲,如果你的项目允许这样也可以参照我这个办法

    点赞 评论
  • blownewbee 2017-12-12 11:27

    目测是jpeg压缩失真,你可以用png格式。

    点赞 评论
  • chen_qiaodan 2017-12-12 12:59
    点赞 评论
  • 云湖之旅 2021-06-16 11:46

    如果图片不是均匀色的,可以尝试一下增加图片DPI,设到300或400看看,setresolution属性,图片是均匀色的话,采用贴图放大试试,直接用C#处理图片本来就比较弱的。

    点赞 评论

相关推荐 更多相似问题