• 基于位图(Bitmap、BitmapData)的图片处理方法(C#)


    目前操作位图的主流方法有三种:

      1、基于Bitmap像素的处理方法,以GetPixel()和SetPixel()方法为主。方法调用简单,但是效率偏低。

      2、基于内存的像素操作方法,以System.Runtime.InteropServices.Marshal.Copy()方法将数据变为非托管资源,操作后再写入内存。

      3、基于指针的操作方式,效率最高,但是对使用者的能力有要求,能力不够者容易造成内存溢出。

    第二种方法的一个实例:

     1 //大图逐行遍历,y为行索引
     2             for (var y = 0; y < destHeight; y++)
     3             {
     4                 //小图。把一行数据读入数组。第一个参数是起始位。
     5                 System.Runtime.InteropServices.Marshal.Copy(srcScan0 + y * srcStride, srcBuffer, 0, srcStride);
     6                 //大图。
     7                 System.Runtime.InteropServices.Marshal.Copy(dstScan0 + y * dstStride, dstBuffer, 0, dstStride);
     8 
     9                 //大图逐列,rgb三色.(与源码相比做了修改,遍历长度减小,数值因为是灰度值,计算了变为了三分之一。)
    10                 for (var x = 0; x < destWidth; x ++)
    11                 {
    12                     //字节总索引
    13                     int fullIndex = 3*x;
    14                     //相乘,再除以255。返回一个byte
    15                     //dstBuffer[x] = channelProcessFunction(ref srcBuffer[x], ref dstBuffer[x]);
    16                     var blendValue = channelProcessFunction(ref srcBuffer[fullIndex], ref dstBuffer[fullIndex]);
    17                     dstBuffer[fullIndex + 2] = blendValue;
    18                     dstBuffer[fullIndex + 1] = blendValue;
    19                     dstBuffer[fullIndex] = blendValue;
    20                 }
    21                 //写回托管内存
    22                 System.Runtime.InteropServices.Marshal.Copy(dstBuffer, 0, dstScan0 + y * dstStride, dstStride);
    23             }
    基于内存的像素操作

    而对于灰度图的处理,可以使用调整gamma值的方式。对于灰度图处理的一个实例:

     1 /// <summary>
     2         /// 把小图片按照权重,重设gamma值,重新渲染。可得到加权重后的小图,背景为白色,非透明。
     3         /// </summary>
     4         /// <param name="image">小图片</param>
     5         /// <param name="weight">权重</param>
     6         /// <returns>加权重后的小图,背景为白色,非透明</returns>
     7         private static Bitmap ApplyHeatValueToImage(Bitmap image, float weight)
     8         {
     9             //新建临时位图
    10             var tempImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb);
    11 
    12             using (var g = Graphics.FromImage(tempImage))
    13             {
    14                 //把权重参数映射为[0.1-5],以便后面进行gamma的矫正。gamma值正常范围为1.0 - 2.2
    15                 //此处拓展,可以让色彩更加intense
    16                 //gamma值可用来进行灰度值层面的明暗矫正,改善失真。
    17                 ////I want to make the color more intense (White/bright)
    18                 if (weight < 0.02f) weight = 0.02f;//最小0.02
    19                 weight *= 5f;
    20                 if (weight > 5f) weight = 5f;
    21 
    22                 // Create ImageAttributes
    23                 var ia = new ImageAttributes();
    24 
    25                 //Gamma values range from 0.1 to 5.0 (normally 0.1 to 2.2), with 0.1 being the brightest and 5.0 the darkest.
    26                 //Convert the 100% to a range of 0.1-5 by multiplying it by 5
    27                 ia.SetGamma(weight, ColorAdjustType.Bitmap);
    28 
    29                 //在image中 重绘
    30                 // Draw Image with the attributes
    31                 g.DrawImage(image,
    32                             new Rectangle(0, 0, image.Width, image.Height),//这里如果size设小一点,可以对目标图像进行缩放。如果小于Graphics的尺寸,则会出现白边
    33                             0, 0, image.Width, image.Height,//这里可以对源图像进行裁剪。
    34                             GraphicsUnit.Pixel, ia);
    35             }
    36             //New dot with a different intensity
    37             return tempImage;
    38         }
  • 相关阅读:
    安装RF
    python-ssh
    视频下载
    【学时总结】◆学时·V◆ 逆元法
    【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final
    【赛时总结】 ◇赛时·III◇ AtCoder ABC-099
    【软件笔记】 ◆笔记·I◆ 各类冷门函数细解
    【学时总结】 ◆学时·IV◆ 数位DP
    【赛时总结】 ◇赛时·I◇ AtCoder ARC-098
    【学时总结】 ◆学时·III◆ 二分图
  • 原文地址:https://www.cnblogs.com/xianerwonder/p/6124658.html
Copyright © 2020-2023  润新知