当前位置: 移动技术网 > IT编程>开发语言>c# > 自己写了个截图工具

自己写了个截图工具

2020年01月10日  | 移动技术网IT编程  | 我要评论
很简单,就是先全屏截图,然后再按需要裁剪就可以了。 所以,首先要获取桌面的大小,代码如下: 使用 PrimaryScreen.DESKTOP 就可以获取桌面分辨率的大小了,有了这个大小,就可以开始全屏截图了,代码如下: 调用 ImageHelper.GetScreen() 即可以获取全屏截图 再然后 ...

很简单,就是先全屏截图,然后再按需要裁剪就可以了。

所以,首先要获取桌面的大小,代码如下:

    public class primaryscreen
    {
        #region win32 api
        [dllimport("user32.dll")]
        static extern intptr getdc(intptr ptr);
        [dllimport("gdi32.dll")]
        static extern int getdevicecaps(
        intptr hdc, // handle to dc
        int nindex // index of capability
        );
        [dllimport("user32.dll", entrypoint = "releasedc")]
        static extern intptr releasedc(intptr hwnd, intptr hdc);
        #endregion
        #region devicecaps常量
        const int horzres = 8;
        const int vertres = 10;
        const int logpixelsx = 88;
        const int logpixelsy = 90;
        const int desktopvertres = 117;
        const int desktophorzres = 118;
        #endregion
        #region 属性
        /// <summary>
        /// 获取屏幕分辨率当前物理大小
        /// </summary>
        public static size workingarea
        {
            get
            {
                intptr hdc = getdc(intptr.zero);
                size size = new size();
                size.width = getdevicecaps(hdc, horzres);
                size.height = getdevicecaps(hdc, vertres);
                releasedc(intptr.zero, hdc);
                return size;
            }
        }
        /// <summary>
        /// 当前系统dpi_x 大小 一般为96
        /// </summary>
        public static int dpix
        {
            get
            {
                intptr hdc = getdc(intptr.zero);
                int dpix = getdevicecaps(hdc, logpixelsx);
                releasedc(intptr.zero, hdc);
                return dpix;
            }
        }
        /// <summary>
        /// 当前系统dpi_y 大小 一般为96
        /// </summary>
        public static int dpiy
        {
            get
            {
                intptr hdc = getdc(intptr.zero);
                int dpix = getdevicecaps(hdc, logpixelsy);
                releasedc(intptr.zero, hdc);
                return dpix;
            }
        }
        /// <summary>
        /// 获取真实设置的桌面分辨率大小
        /// </summary>
        public static size desktop
        {
            get
            {
                intptr hdc = getdc(intptr.zero);
                size size = new size();
                size.width = getdevicecaps(hdc, desktophorzres);
                size.height = getdevicecaps(hdc, desktopvertres);
                releasedc(intptr.zero, hdc);
                return size;
            }
        }

        /// <summary>
        /// 获取宽度缩放百分比
        /// </summary>
        public static float scalex
        {
            get
            {
                intptr hdc = getdc(intptr.zero);
                int t = getdevicecaps(hdc, desktophorzres);
                int d = getdevicecaps(hdc, horzres);
                float scalex = (float)getdevicecaps(hdc, desktophorzres) / (float)getdevicecaps(hdc, horzres);
                releasedc(intptr.zero, hdc);
                return scalex;
            }
        }
        /// <summary>
        /// 获取高度缩放百分比
        /// </summary>
        public static float scaley
        {
            get
            {
                intptr hdc = getdc(intptr.zero);
                float scaley = (float)(float)getdevicecaps(hdc, desktopvertres) / (float)getdevicecaps(hdc, vertres);
                releasedc(intptr.zero, hdc);
                return scaley;
            }
        }
        #endregion
    }

使用 primaryscreen.desktop 就可以获取桌面分辨率的大小了,有了这个大小,就可以开始全屏截图了,代码如下:

public class imagehelper
    {
        /// <summary>
        /// 截取全屏
        /// </summary>
        /// <returns></returns>
        public static bitmap getscreen()
        {
            size screensize = primaryscreen.desktop;
            bitmap bmp = new bitmap(screensize.width, screensize.height);
            using (graphics g = graphics.fromimage(bmp))
                g.copyfromscreen(0, 0, 0, 0, new size(screensize.width, screensize.height));
            return bmp;
        }

        /// <summary>
        /// 图像明暗调整
        /// </summary>
        /// <param name="b">原始图</param>
        /// <param name="degree">亮度[-255, 255]</param>
        public static void lighten(bitmap b, int degree)
        {
            if (b == null)
            {
                //return null;
                return;
            }

            if (degree < -255) degree = -255;
            if (degree > 255) degree = 255;

            try
            {

                int width = b.width;
                int height = b.height;

                int pix = 0;

                bitmapdata data = b.lockbits(new rectangle(0, 0, width, height), imagelockmode.readwrite, pixelformat.format24bpprgb);

                unsafe
                {
                    byte* p = (byte*)data.scan0;
                    int offset = data.stride - width * 3;
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // 处理指定位置像素的亮度
                            for (int i = 0; i < 3; i++)
                            {
                                pix = p[i] + degree;

                                if (degree < 0) p[i] = (byte)math.max(0, pix);
                                if (degree > 0) p[i] = (byte)math.min(255, pix);

                            } // i
                            p += 3;
                        } // x
                        p += offset;
                    } // y
                }

                b.unlockbits(data);

                //return b;
            }
            catch
            {
                //return null;
            }

        } // end of lighten
    }

调用 imagehelper.getscreen() 即可以获取全屏截图

再然后,为了实现区域截图,我们需要把全屏截图放到一个窗体里面进行裁剪,弹出裁剪窗体的代码如下:

private void button1_click(object sender, eventargs e)
{
    this.opacity = 0; //先隐藏自己
    bitmap bitmap = imagehelper.getscreen(); //截取全屏
    getscreenform frm = new getscreenform(bitmap); //准备区域截图
    frm.showdialog(); //弹出区域截图界面
    this.opacity = 1; //显示自己
}

 

区域截图的代码有点多,无非就是鼠标按下、移动、松开的相关处理,以对全屏截图进行裁剪处理,代码如下:

    public partial class getscreenform : form
    {
        /// <summary>
        /// 亮图(原图)
        /// </summary>
        public bitmap bitmap { get; set; }

        /// <summary>
        /// 暗图
        /// </summary>
        public bitmap bitmap2 { get; set; }

        /// <summary>
        /// 屏幕的宽
        /// </summary>
        public int w { get; set; }
        /// <summary>
        /// 屏幕的高
        /// </summary>
        public int h { get; set; }
        /// <summary>
        /// 适用于高dpi的宽度
        /// </summary>
        public int w2 { get; set; }
        /// <summary>
        /// 适用于高dpi的高度
        /// </summary>
        public int h2 { get; set; }

        graphics g;
        bitmap cache;
        graphics gmain;

        /// <summary>
        /// 构造方法
        /// </summary>
        public getscreenform(bitmap bitmap)
        {
            //亮图 (也就是原图)
            this.bitmap = bitmap;
            this.w = bitmap.width;
            this.h = bitmap.height;

            //暗图
            this.bitmap2 = new bitmap(bitmap.width, bitmap.height);
            using (graphics g = graphics.fromimage(bitmap2))
                g.drawimage(bitmap, 0, 0);
            imagehelper.lighten(bitmap2, -100);
            //求出适用于高dpi的宽和高
            w2 = (int)(bitmap2.width * primaryscreen.scalex);
            h2 = (int)(bitmap2.height * primaryscreen.scaley);
            //初始化
            initializecomponent();
            this.width = (int)(this.w / primaryscreen.scalex);
            this.height = (int)(this.h / primaryscreen.scaley);
            //绘图相关
            cache = new bitmap(this.w, this.h);
            gmain = this.creategraphics();
            g = graphics.fromimage(cache);
        }

        /// <summary>
        /// 双击关闭
        /// </summary>
        protected override void ondoubleclick(eventargs e)
        {
            //获取截图 
            if (sx > int.minvalue && sy > int.minvalue)
            {
                //获取区域
                int x1 = sx, x2 = sx + sw;
                if (x1 > x2) { x2 = x1 + x2; x1 = x2 - x1; x2 = x2 - x1; };
                int y1 = sy, y2 = sy + sh;
                if (y1 > y2) { y2 = y1 + y2; y1 = y2 - y1; y2 = y2 - y1; };
                //截图
                bitmap bmp = new bitmap(x2 - x1, y2 - y1);
                graphics g6 = graphics.fromimage(bmp);
                g6.drawimage(bitmap,
                    new rectangle(0, 0, bmp.width, bmp.height),
                    new rectangle((int)(x1 * primaryscreen.scalex), (int)(y1 * primaryscreen.scaley), (int)((x2 - x1) * primaryscreen.scalex), (int)((y2 - y1) * primaryscreen.scaley)),
                    graphicsunit.pixel);
                bmp.save("x.jpg", imageformat.jpeg);
            }
            this.close();
        }

        private void getscreenform_load(object sender, eventargs e)
        {

        }

        protected override void onshown(eventargs e)
        {
            drawform();
        }

        void drawform()
        {
            //画暗图
            g.drawimage(bitmap2,
                new rectangle(0, 0, w, h),   //目标
                new rectangle(0, 0, w2, h2), //源
                graphicsunit.pixel);

            //画亮图
            if (sx > int.minvalue && sy > int.minvalue)
            {
                g.drawimage(bitmap,
                    new rectangle(sx, sy, sw, sh),
                    new rectangle((int)(sx * primaryscreen.scalex), (int)(sy * primaryscreen.scaley), (int)(sw * primaryscreen.scalex), (int)(sh * primaryscreen.scaley)),
                    graphicsunit.pixel);
                //new rectangle(sx, sy, sw, sh),   //目标
                //new rectangle(sx, sy, sw, sh),   //源
                //graphicsunit.pixel);
            }

            //翻转
            gmain.drawimage(cache, 0, 0);
        }

        /// <summary>
        /// 选择的区域
        /// </summary>
        public int sx { get; set; } = int.minvalue;
        public int sy { get; set; } = int.minvalue;
        public int sw { get; set; }
        public int sh { get; set; }

        /// <summary>
        /// 工作类型 0未工作 1画框 2移框
        /// </summary>
        public int worktype { get; set; }

        /// <summary>
        /// 移动的起点
        /// </summary>
        public int movex { get; set; }
        public int movey { get; set; }

        protected override void onmousedown(mouseeventargs e)
        {
            //判断是不是点击在框里
            bool inside = false;
            if (sx > int.minvalue && sy > int.minvalue)
            {
                int x1 = sx, x2 = sx + sw;
                if (x1 > x2) { x2 = x1 + x2; x1 = x2 - x1; x2 = x2 - x1; };
                int y1 = sy, y2 = sy + sh;
                if (y1 > y2) { y2 = y1 + y2; y1 = y2 - y1; y2 = y2 - y1; };
                if (e.x > x1 && e.x < x2
                    && e.y > y1 && e.y < y2)
                {
                    inside = true;
                }
            }
            if (inside)
            {
                //在框里,则进行移框
                this.movex = e.x;
                this.movey = e.y;
                this.worktype = 2;
                drawform();
            }
            else
            {
                //在框外,则重新画框
                this.sx = e.x;
                this.sy = e.y;
                this.sw = 0;
                this.sh = 0;
                this.worktype = 1;
                drawform();
            }
        }

        protected override void onmousemove(mouseeventargs e)
        {
            if (e.button == mousebuttons.left)
            {
                if (this.worktype == 1)
                {
                    //画框
                    this.sw = e.x - this.sx;
                    this.sh = e.y - this.sy;
                }
                else
                {
                    //移框
                    this.sx += e.x - this.movex;
                    this.sy += e.y - this.movey;
                    this.movex = e.x;
                    this.movey = e.y;
                }
                drawform();
            }
        }

        protected override void onmouseup(mouseeventargs e)
        {
            if (this.worktype == 1)
            {
                this.sw = e.x - this.sx;
                this.sh = e.y - this.sy;
            }
            this.worktype = 0;
            drawform();
        }
    }

 

提供源代码给大家玩玩,点这里下载源代码

 

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网