非完美主义者 2017-12-12 10:20 采纳率: 50%
浏览 1705
已采纳

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软件而且还要长期保持运行,而且也比较慢,但效果真的碾压所谓的各种无损压缩,刚好我的项目对质量非常高,效率可以适当做出牺牲,如果你的项目允许这样也可以参照我这个办法

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 用verilog实现tanh函数和softplus函数
  • ¥15 Hadoop集群部署启动Hadoop时碰到问题
  • ¥15 求京东批量付款能替代天诚
  • ¥15 slaris 系统断电后,重新开机后一直自动重启
  • ¥15 QTableWidget重绘程序崩溃
  • ¥15 谁能帮我看看这拒稿理由啥意思啊阿啊
  • ¥15 关于vue2中methods使用call修改this指向的问题
  • ¥15 idea自动补全键位冲突
  • ¥15 请教一下写代码,代码好难
  • ¥15 iis10中如何阻止别人网站重定向到我的网站