截图小工具开发笔记

一、开发环境及工具

Windows 7 系统,开发软件为Microsoft Visual Studio Ultimate 2012

二、实现的功能

屏幕截屏,保存到图片或者保存到剪切板。截屏范围可以随意移动或者改变大小,自由度很高。先预览一下效果:

三、实现原理

2个窗体,1个是主窗体,主要功能进行热键设置,抓取屏幕到图片传给另一个窗体,另一个窗体对传过来的图片继续截取等操作。

四、开发手记

1.新建winform项目

2.主界面设计如图:

窗体主要属性设置如下:

//窗口样式
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
//窗口图标
  this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
//禁止最大化            
this.MaximizeBox = false;
//窗口名称
 this.Name = "PicCut";
//窗口初始位置为屏幕中心
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
//窗口标题为“截图设置”
this.Text = "截图设置";
//窗口浮在所有窗口上面
 this.TopMost = true;

 

 

此窗口内主要包括2label控件,1ComboBox1PictureBox,摆放位置如上图。label用于显示文字说明;ComboBox用于显示热键09个数字供选择;PictureBox用于显示二维码图片。

3.主界面的主要功能是对热键进行设置,同时我们程序运行,该界面自动最小化到托盘,双击进行截图,有机显示上述主界面进行设置,设置完毕可以最小化自动到托盘,点击关闭程序会自动退出。

 

1)自动到托盘

主界面拖入“notifyIcon”,主要属性设置如下图,其中Text是鼠标滑动到拖盘区域图标上的提示;Icon是托盘图标;Visible设置为false,默认不显示托盘区域图标。

 

 

主要程序代码。窗体载入时,最小化窗体,同时设置ComboBox空间的默认值。

private void PicCut_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized; NumberCbox.SelectedIndex = CutPicSet.Default.KeyNumber; }

 

窗口大小发生变化时,如果窗口最小化,隐藏当前窗体,托盘区域显示图标。

private void PicCut_SizeChanged(object sender, EventArgs e)
 {
           if (this.WindowState == FormWindowState.Minimized)
            {
                 this.Hide();
                MinNot.Visible = true;   
            }
 }

 

上述两段代码实现了,程序开始运行时候,窗口最小化隐藏,同时托盘区域显示图标。

(2)托盘图标左键双击进行截图操作

private void MinNot_MouseDoubleClick(object sender, MouseEventArgs e)
{
      if (e.Button==MouseButtons.Left)
     {
//显示截图窗体
ShowCutPic(); } }

 

ShowCutPic函数:
protected void ShowCutPic()
        {
            // 创建的空白图片和屏幕大小一样大的图片
            Bitmap CatchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);            
            // 我们可以通过Graphics这个类在这个空白图片上画图
            Graphics g = Graphics.FromImage(CatchBmp);
            // 把屏幕图片拷贝到我们创建的空白图片 CatchBmp中
            g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));
            //这个我们截图的窗体创建截图窗体
            cutter = new CutPic();
             // 截图窗体的图片属性设置我们刚才新建的图片;
            cutter.Image = CatchBmp;
           //显示窗体
            cutter.ShowDialog();
        }

 

 

3)托盘图标右键单击显示界面设置
 private void MinNot_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button== MouseButtons.Right)
            {
//显示主窗体
                this.Show();
//隐藏托盘图标
                MinNot.Visible = false;
//当前窗口普通设置
                this.WindowState = FormWindowState.Normal;               
            }
                   
        }

 

4)热键设置
/// <summary>
        /// 如果函数执行成功,返回值不为0。
        /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。
        /// </summary>
        /// <param name="hWnd">要定义热键的窗口的句柄</param>
        /// <param name="id">定义热键ID(不能与其它ID重复)</param>
        /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
        /// <param name="vk">定义热键的内容</param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);

        /// <summary>
        /// 注销热键
        /// </summary>
        /// <param name="hWnd">要取消热键的窗口的句柄</param>
        /// <param name="id">要取消热键的ID</param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        /// <summary>
        /// 辅助键名称。
        /// Alt, Ctrl, Shift, WindowsKey
        /// </summary>
        [Flags()]
        public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 }

        /// <summary>
        /// 注册热键
        /// </summary>
        /// <param name="hwnd">窗口句柄</param>
        /// <param name="hotKey_id">热键ID</param>
        /// <param name="keyModifiers">组合键</param>
        /// <param name="key">热键</param>
        public static void RegHotKey(IntPtr hwnd, int hotKeyId, KeyModifiers keyModifiers, Keys key)
        {
            if (!RegisterHotKey(hwnd, hotKeyId, keyModifiers, key))
            {
                int errorCode = Marshal.GetLastWin32Error();
                if (errorCode == 1409)
                {
                    MessageBox.Show("热键被占用 !");
                }
                else
                {
                    MessageBox.Show("注册热键失败!错误代码:" + errorCode);
                }
            }
        }

        /// <summary>
        /// 注销热键
        /// </summary>
        /// <param name="hwnd">窗口句柄</param>
        /// <param name="hotKey_id">热键ID</param>
        public static void UnRegHotKey(IntPtr hwnd, int hotKeyId)
        {
            //注销指定的热键
            UnregisterHotKey(hwnd, hotKeyId);
        }
private const int WM_HOTKEY = 0x312; //窗口消息-热键
        private const int WM_CREATE = 0x1; //窗口消息-创建
        private const int WM_DESTROY = 0x2; //窗口消息-销毁
        private const int Space = 0x3572; //热键ID
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch (m.Msg)
            {
                case WM_HOTKEY: //窗口消息-热键ID
                    switch (m.WParam.ToInt32())
                    {
                        case Space: //热键ID
//按下热键显示截图窗体
                            ShowCutPic();
                            break;
                        default:
                            break;
                    }
                    break;
                case WM_CREATE: //窗口消息-创建
                    SetHotKey(CutPicSet.Default.KeyNumber);
                    break;
                case WM_DESTROY: //窗口消息-销毁
                    UnRegHotKey(Handle, Space); //销毁热键
                    break;
                default:
                    break;
            }
        }

        public void SetHotKey(int keynumber)
        {
            if (keynumber == 0)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D0);
            }
            else if (keynumber == 1)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D1);
            }
            else if (keynumber == 2)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D2);
            }
            else if (keynumber == 3)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D3);
            }
            else if (keynumber == 4)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D4);
            }
            else if (keynumber == 5)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D5);
            }
            else if (keynumber == 6)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D6);
            }
            else if (keynumber == 7)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D7);
            }
            else if (keynumber == 8)
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D8);
            }
            else
            {
                RegHotKey(Handle, Space, KeyModifiers.Ctrl, Keys.D9);
            }
        }

 

 5)图形热键设置
 private void NumberCbox_SelectedIndexChanged(object sender, EventArgs e)
        {
//把配置文件设置NumberCbox的选择值
            CutPicSet.Default.KeyNumber = NumberCbox.SelectedIndex;
            CutPicSet.Default.Save();
//先卸载原来注册的热键
            UnRegHotKey(Handle, Space);
//从新设置选择的热键
            SetHotKey(NumberCbox.SelectedIndex);
        }

 

4、截图界面设计

新建窗体CutPic,名称与之前的名称相对应,主要属性设置如下:

Name:CutPic

WindowState:Maximized

TopMost:true

FormBorderStyle:None

5、截图功能实现

主要代码如下:

 private Point m_ptStart;        //起始点位置
        private Point m_ptCurrent;      //当前鼠标位置
        private Point m_ptTempForMove;  //移动选框的时候临时用
        private Rectangle m_rectClip;   //限定鼠标活动的区域
        private Rectangle[] m_rectDots = new Rectangle[8];  //八个控制点
        protected bool m_bMoving;
        protected bool m_bChangeWidth;
        protected bool m_bChangeHeight;
        protected bool m_bMouseHover;
        private bool _IsDrawed; /// 获取当前是否已经选择区域
        private Image _Image;
        ///
        /// 要裁剪的图像
        ///
        [Description("要裁剪的图像"), Category("Customs")]
        public Image Image
        {
            get { return _Image; }
            set
            {
                if (value == this._Image) return;
                _Image = value;
             //   this.Clear();
            }
        }
        private Color _MaskColor = Color.FromArgb(125, 0, 0, 0);
        ///
        /// 遮罩颜色
        ///
        [Description("遮罩颜色"), Category("Customs")]
        public Color MaskColor
        {
            get { return _MaskColor; }
            set
            {
                if (_MaskColor == value) return;
                _MaskColor = value;
                if (this._Image != null) this.Invalidate();
            }
        }
        private Rectangle _SelectedRectangle;/// 获取或设置悬着区域
       
        public CutPic()
        {
            SetStyle(ControlStyles.UserPaint, true);  
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.  
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲  

            InitializeComponent();
        }

        private void CutPic_MouseDown(object sender, MouseEventArgs e)
        {
            if (this._Image == null)
            {
                return;//Image属性null或者已经锁定选择 直接返回
            }
            m_ptStart = e.Location;
            m_bChangeHeight = true;
            m_bChangeWidth = true;

            //判断若不在限定范围内操作 返回
            m_rectClip = this.DisplayRectangle;
                Size sz = this.Size;
                sz = this.Size;                
                m_rectClip.Intersect(new Rectangle(Point.Empty, sz));
                m_rectClip.Width++; m_rectClip.Height++;
                Cursor.Clip = RectangleToScreen(m_rectClip);
            

            if (ToolsPanel.Visible==true)
            {
                ToolsPanel.Visible = false;
            }
            //如果 已经选择区域 若鼠标点下 判断是否在控制顶点上
            if (this._IsDrawed)
            {
                this._IsDrawed = false; //默认表示 要更改选取设置 清楚IsDrawed属性
                if (m_rectDots[0].Contains(e.Location))
                {
                    m_ptStart.X = this._SelectedRectangle.Right;
                    m_ptStart.Y = this._SelectedRectangle.Bottom;
                }
                else if (m_rectDots[1].Contains(e.Location))
                {
                    m_ptStart.Y = this._SelectedRectangle.Bottom;
                    m_bChangeWidth = false;
                }
                else if (m_rectDots[2].Contains(e.Location))
                {
                    m_ptStart.X = this._SelectedRectangle.X;
                    m_ptStart.Y = this._SelectedRectangle.Bottom;
                }
                else if (m_rectDots[3].Contains(e.Location))
                {
                    m_ptStart.X = this._SelectedRectangle.Right;
                    m_bChangeHeight = false;
                }
                else if (m_rectDots[4].Contains(e.Location))
                {
                    m_ptStart.X = this._SelectedRectangle.X;
                    m_bChangeHeight = false;
                }
                else if (m_rectDots[5].Contains(e.Location))
                {
                    m_ptStart.X = this._SelectedRectangle.Right;
                    m_ptStart.Y = this._SelectedRectangle.Y;
                }
                else if (m_rectDots[6].Contains(e.Location))
                {
                    m_ptStart.Y = this._SelectedRectangle.Y;
                    m_bChangeWidth = false;
                }
                else if (m_rectDots[7].Contains(e.Location))
                {
                    m_ptStart = this._SelectedRectangle.Location;
                }
                else if (this._SelectedRectangle.Contains(e.Location))
                {
                    m_bMoving = true;
                    m_bChangeWidth = false;
                    m_bChangeHeight = false;
                }
                else { this._IsDrawed = true; }   //若以上条件不成立 表示不需要更改设置
            }
        }

        private void CutPic_MouseClick(object sender, MouseEventArgs e)
        {
            if (MouseButtons.Right==e.Button)
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void CutPic_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (_Image!=null)
            {
                  g.DrawImage(this._Image,0,0,this._Image.Width,this._Image.Height);//原图
                  using (SolidBrush sb = new SolidBrush(this._MaskColor))
                  {
                      g.FillRectangle(sb, this.ClientRectangle);//遮罩
                  }
                  if (!this._SelectedRectangle.IsEmpty)
                      this.DrawSelectedRectangle(g);//选框
            }
            SetPanleLocation();
        }

        private void CutPic_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 8; i++)
            {
                m_rectDots[i].Size = new Size(5, 5);
            }        
                          
            m_ptTempForMove = this.DisplayRectangle.Location;
          
        }

        private void CutPic_MouseMove(object sender, MouseEventArgs e)
        {
            m_ptCurrent = e.Location;
            if (this._Image == null)
            {
                return;
            }
            if (this._IsDrawed)
            {//如果已经绘制 移动过程中判断是否需要设置鼠标样式
                this.SetCursorStyle(e.Location);
            }
            else if (e.Button == MouseButtons.Left)
            {//否则可能表示在选择区域或重置大小
                if (m_bChangeWidth)
                {//是否允许选区宽度改变 如重置大小时候 拉动上边和下边中点时候
                    this._SelectedRectangle.X = e.Location.X > m_ptStart.X ? m_ptStart.X : e.Location.X;
                    this._SelectedRectangle.Width = Math.Abs(e.Location.X - m_ptStart.X);
                }
                if (m_bChangeHeight)
                {
                    this._SelectedRectangle.Y = e.Location.Y > m_ptStart.Y ? m_ptStart.Y : e.Location.Y;
                    this._SelectedRectangle.Height = Math.Abs(e.Location.Y - m_ptStart.Y);
                }
                if (m_bMoving)
                {//如果是移动选区 判断选区移动范围
                    int tempX = m_ptTempForMove.X + e.X - m_ptStart.X;
                    int tempY = m_ptTempForMove.Y + e.Y - m_ptStart.Y;
                    
                    if (tempX < 0) tempX = 0;
                        if (tempY < 0) tempY = 0;
                        if (this._SelectedRectangle.Width + tempX >= m_rectClip.Width) tempX = m_rectClip.Width - this._SelectedRectangle.Width - 1;
                        if (this._SelectedRectangle.Height + tempY >= m_rectClip.Height) tempY = m_rectClip.Height - this._SelectedRectangle.Height - 1;
                   
                    this._SelectedRectangle.X = tempX;
                    this._SelectedRectangle.Y = tempY;
                }
                this.Invalidate();
            }
            else if (!this._IsDrawed)
            {
                this.Invalidate();//否则 在需要绘制放大镜并且还没有选好区域同时 都重绘
            }
        }
        ///
        /// 判断鼠标当前位置显示样式
        ///
        /// 鼠标坐标
        protected virtual void SetCursorStyle(Point pt)
        {
            if (m_rectDots[0].Contains(pt) || m_rectDots[7].Contains(pt))
                this.Cursor = Cursors.SizeNWSE;
            else if (m_rectDots[1].Contains(pt) || m_rectDots[6].Contains(pt))
                this.Cursor = Cursors.SizeNS;
            else if (m_rectDots[2].Contains(pt) || m_rectDots[5].Contains(pt))
                this.Cursor = Cursors.SizeNESW;
            else if (m_rectDots[3].Contains(pt) || m_rectDots[4].Contains(pt))
                this.Cursor = Cursors.SizeWE;
            else if (this._SelectedRectangle.Contains(pt))
                this.Cursor = Cursors.SizeAll;
            else
                this.Cursor = Cursors.Default;
        }

        private void CutPic_MouseUp(object sender, MouseEventArgs e)
        {
            this._IsDrawed = !this._SelectedRectangle.IsEmpty;
            m_ptTempForMove = this._SelectedRectangle.Location;
            m_bMoving = false;
            m_bChangeWidth = false;
            m_bChangeHeight = false;
            Cursor.Clip = Rectangle.Empty;
            ToolsPanel.Visible = true;
            this.Invalidate();

            
           
        }

        public void SetPanleLocation()
        {
            ToolsPanel.Left = this._SelectedRectangle.Left + this._SelectedRectangle.Width - ToolsPanel.Width;
            ToolsPanel.Top =  this._SelectedRectangle.Top+this._SelectedRectangle.Height+5;
        }


        ///
        /// 绘制选框
        ///
        /// 绘图表面
        protected virtual void DrawSelectedRectangle(Graphics g)
        {
            m_rectDots[0].Y = m_rectDots[1].Y = m_rectDots[2].Y = this._SelectedRectangle.Y - 2;
            m_rectDots[5].Y = m_rectDots[6].Y = m_rectDots[7].Y = this._SelectedRectangle.Bottom - 2;
            m_rectDots[0].X = m_rectDots[3].X = m_rectDots[5].X = this._SelectedRectangle.X - 2;
            m_rectDots[2].X = m_rectDots[4].X = m_rectDots[7].X = this._SelectedRectangle.Right - 2;
            m_rectDots[3].Y = m_rectDots[4].Y = this._SelectedRectangle.Y + this._SelectedRectangle.Height / 2 - 2;
            m_rectDots[1].X = m_rectDots[6].X = this._SelectedRectangle.X + this._SelectedRectangle.Width / 2 - 2;

            g.DrawImage(this._Image, this._SelectedRectangle, this._SelectedRectangle, GraphicsUnit.Pixel);
            g.DrawRectangle(Pens.Cyan, this._SelectedRectangle.Left, this._SelectedRectangle.Top, this._SelectedRectangle.Width - 1, this._SelectedRectangle.Height - 1);
            foreach (Rectangle rect in m_rectDots)
                g.FillRectangle(Brushes.Yellow, rect);
            string str = string.Format("X:{0} Y:{1} W:{2} H:{3}",
                this._SelectedRectangle.Left, this._SelectedRectangle.Top, this._SelectedRectangle.Width, this._SelectedRectangle.Height);
            Size szStr = g.MeasureString(str, this.Font).ToSize();
            Point ptStr = new Point(this._SelectedRectangle.Left, this._SelectedRectangle.Top - szStr.Height - 5);
            if (ptStr.Y < 0) ptStr.Y = this._SelectedRectangle.Top + 5;
            if (ptStr.X + szStr.Width > this.Width) ptStr.X = this.Width - szStr.Width;
            using (SolidBrush sb = new SolidBrush(Color.FromArgb(125, 0, 0, 0)))
            {
                g.FillRectangle(sb, new Rectangle(ptStr, szStr));
                g.DrawString(str, this.Font, Brushes.White, ptStr);
            }
        }

        private void SaveBT_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.FileName = DateTime.Now.ToString("yyyyMMddhhmmss");
            saveFileDialog.Filter = "png|*.png|bmp|*.bmp|jpg|*.jpg|gif|*.gif";
            if (saveFileDialog.ShowDialog() != DialogResult.Cancel)
            {
                System.Drawing.Rectangle cropArea = new System.Drawing.Rectangle(_SelectedRectangle.X, _SelectedRectangle.Y, _SelectedRectangle.Width, _SelectedRectangle.Height);
                Bitmap bmpImage = new Bitmap(this._Image);
                Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
                bmpCrop.Save(saveFileDialog.FileName);
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                this.Focus();
            }
        }
       

        private void CutPic_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this._SelectedRectangle.Contains(e.Location))
            {
                //复制图片到剪切板
                System.Drawing.Rectangle cropArea = new System.Drawing.Rectangle(_SelectedRectangle.X, _SelectedRectangle.Y, _SelectedRectangle.Width, _SelectedRectangle.Height);
                Bitmap bmpImage = new Bitmap(this._Image);
                Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
                Clipboard.SetImage(bmpCrop);
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }
//如果按下ESC键退出截图功能
        private void CutPic_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyValue==27)
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

 

这样截图功能就已经实现了。源代码下载,请点击

 

转载于:https://www.cnblogs.com/agoodlife/p/10849653.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
截图时可能首先大家能想到的肯定是最简单原始的Print Screen万能键。优点显而易见。但是也有缺点:其一,虽然简单,但是不一定方便,很多时候,我们并不是需要截取整个屏幕,而是局部,比如某个应用程序窗口等。这个时候就需要打开画图版再行截图,不是太方便。第二,自动屏蔽鼠标,鼠标没有被包含到截图中,有些时候不要鼠标可能截图更清爽,但是很多时候我们想截图鼠标使我们的实力更清晰(比如用鼠标指向某个应用程序的菜单或者按钮)。 Greenshot是一款免费、开源的屏幕截图工具,通过快捷键即可进行截图:区域截图(Print),窗口截图(Alt+Print)和全屏截图(Ctrl+Print),并且自带一个小巧的图像编辑器,可以即时编辑抓下来的图片。基于C#开发,支持插件扩展,非常适合替代商业抓图软件如SnagIt或Hyper-Snap等。 虽然体积很小,但是其功能却毫不含糊,该有的功能都有了,只所谓麻雀虽小五脏俱全。通过快捷键即可进行截图:区域截图(Print),窗口截图(Alt+Print)和全屏截图(Ctrl+Print)。如果是笔记本,截图快捷键貌似需要+Fn键。(在HP笔记本上是这样的) 此外,你可以通过右键单击任务栏上Greenshot的图标进行软件设置。如果你不喜欢截图后直接跳到编辑界面,那么在右键菜单的“快速设定”中可以更改。甚至可以直接保存,这样就不会拖泥带水,步骤也是最少。 Greenshot 功能特色: 1、添加方框和椭圆。你可以设置这些添加的图形是否有边框,填充的颜色是什么,还能够更改透明程度哦。这样就不会完全遮住背景,成为绚丽的加亮。边框的粗细也可以调节,默认是1px。 2、绘制直线和箭头。箭头可以两端都有,或者只有一端。 3、添加文字。文字区域也可以调节背景颜色。 4、高亮显示。这个功能一共有四个模式。高亮文字(用颜色突出选定区域)、高亮区域(模糊未被选定的所有区域)、灰阶(为选定区域黑白)和放大(大放选定区域)。 5、如果你想要对部分图片打马赛克,可以使用模糊功能。 以上5种功能中,1和3在其他同类软件中是非常少见的。而如果你使用熟练的话,那么会给你的截图增色不少。 或者你非常喜欢这个软件自带的图片编辑器,那么“从文件载入图片”这个右键菜单,就可以用它来编辑任何图像了。
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
### 回答1: POATY是一款非常实用的开发笔记工具。它提供了强大的功能,有助于程序员和开发人员更加高效地记录和管理自己的笔记。 首先,POATY具有简洁直观的界面设计,使得用户能够快速上手并迅速上手。它采用了一个类似于文本编辑器的界面,使得用户可以方便地创建、编辑和组织自己的笔记。 其次,POATY支持多种内容格式,包括文字、代码块、图片等。程序员可以在笔记中添加代码块,轻松显示和分享自己的代码片段。此外,POATY还支持数学公式,方便用户编写数学相关的笔记。 此外,POATY还具有强大的搜索和过滤功能。用户可以通过关键字搜索笔记,快速找到自己想要的内容。POATY还可以根据标签或日期进行筛选,帮助用户更好地组织和管理自己的笔记。 另外,POATY还支持实时同步功能。用户可以将笔记存储在云端,方便在不同设备上进行访问和编辑。这样用户就可以随时随地记录和查看自己的笔记,提高工作效率。 总之,POATY是一款功能强大、易于使用的开发笔记工具。它提供了丰富的功能,帮助用户更好地组织和管理自己的开发笔记。无论是程序员还是开发人员,都可以从POATY中受益,并提高自己的工作效率。 ### 回答2: Pota是一款功能强大的笔记工具,专门为开发人员设计。它提供了一种便捷的方式来记录和组织开发过程中的想法、代码片段、文档和其他重要信息。 首先,Pota支持多种语言的代码高亮显示,让开发者能够更清晰地阅读和编辑代码,提高编码效率。它还提供了自动补全和错误检查等功能,帮助开发者更快地编写出高质量的代码。 其次,Pota具备强大的搜索与过滤功能。开发人员可以通过关键词搜索他们的笔记,或者根据不同的标签、日期、文件类型等进行过滤,以快速找到所需内容。这有助于节省开发者的时间和精力,提高他们的工作效率。 此外,Pota还提供了团队协作功能。开发人员可以创建团队,并与其它成员共享笔记和文档。这使得团队成员可以方便地共同讨论和编辑项目相关的内容,促进团队的合作和沟通。 最后,Pota支持多种平台和设备的同步。开发人员可以在电脑、手机和平板等不同设备上使用Pota,并实现实时同步,以便随时随地访问和更新他们的笔记。 总结而言,Pota作为一款开发笔记工具,以其丰富的功能和便捷的使用体验,方便了开发人员的日常工作和合作。无论是个人开发者还是团队项目,Pota都能为他们带来更高的效率和更好的开发体验。 ### 回答3: Poaaty是一款功能强大的开发笔记工具。它提供了丰富的功能,助力开发人员更高效地记录和管理自己的开发笔记。 首先,Poaaty具有简洁直观的用户界面,使得用户能够轻松创建、编辑和查找笔记。用户可以根据自己的需要创建不同的笔记本,并在每个笔记本内创建多个笔记。每个笔记还可以添加标签,方便用户对笔记进行分类和搜索。同时,Poaaty支持实时同步功能,可以将笔记内容自动同步到各个设备上,无论是在电脑上还是手机上,用户都可以随时随地访问和编辑笔记。 其次,Poaaty还具备强大的代码编辑功能。它支持多种开发语言的语法高亮显示,使得代码更加清晰易读。用户还可以将代码片段进行整理和保存,方便以后重复使用。此外,Poaaty还提供了实时预览功能,在编写代码的同时,用户可以即时查看代码的运行效果,提高开发效率。 此外,Poaaty还支持与其他开发工具的集成,例如Git和JIRA。用户可以将笔记与项目代码进行关联,方便跟踪和管理开发进展。同时,Poaaty还支持导入和导出功能,用户可以方便地将笔记导出为常见的文件格式,如Markdown和HTML。 总之,Poaaty是一款功能齐全、易用便捷的开发笔记工具,它能够帮助开发人员更好地记录、管理和分享开发笔记,提高开发效率,是开发人员必备的工具之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值