(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Минималистичный скриншотер на .NET

Источник: habrahabr
habrahabr

Минималистичный скриншотер на .NET

Лучше один раз увидеть, чем 100 раз услышать.
Уверен, не я один часто делаю скриншоты.
Проиллюстрировать баг, отправить смешную картинку знакомому,
вставить в комментарий на каком-нибудь ресурсе, etc.
А началось всё с разочарования в некогда любимом Gyazo,
а именно сам скриншот уже трудно найти под кучей рекламных блоков.
Когда я пересмотрел аналоги, они мне показались чересчур громоздкими.
Пройти через несколько окон, чтобы просто сделать скриншот? Нет, спасибо.

И вот, желая облегчить себе жизнь, а заодно ответить на вопрос
было решено сделать всё самому.

Суть

А хочется то предельно простого.
Один клик - запустить приложение, второй клик - выделить область на экране.
Всё - после этого видим скриншот уже в браузере (в PNG) и имеем ссылку на него в буфере обмена.

Примерный алгоритм работы видится мне таким:

  • При запуске программа делает скриншот.
  • Устанавливает его фоном для окна, развёрнутого на весь экран.
  • Мышкой выделяем нужную область на экране.
  • Готово, картинка улетает на сервер.


Как и ожидалось, возникла аналогичная проблема с мерцанием.
Для устранения установим форме свойство DoubleBuffered.


DoubleBuffered = true;

К сожалению помогло только частично. На просторах интернета был найден совет
отправить функции CreateWindowEx сообщение WS_CLIPCHILDREN в параметре dwExStyle.
Сделать это можно переопределив CreateParams.


protected override CreateParams CreateParams
{
   get
   {
      CreateParams cp = base.CreateParams;
      cp.ExStyle /= 0x02000000;
      return cp;
   }
}

Загружаются скриншоты на imgur, присутсвует простой апи.
Для использования нужен api key, регистрируем приложение - получаем тут же ключ.
Отправляем картинку:


class Uploader
{
   private static string imgur_key = null;

   public static string IMGUR_KEY
   {
      set { imgur_key = value; }
   }
   public static string UploadToImgur(Bitmap bitmap, ImageFormat imgFormat)
   {
      MemoryStream memStream = new MemoryStream();
      bitmap.Save(memStream, imgFormat);
      using (WebClient wc = new WebClient())
      {
         NameValueCollection values = new NameValueCollection
         {
            { "key", imgur_key },
            { "image", Convert.ToBase64String(memStream.ToArray()) }
         };
         byte[] response = wc.UploadValues("http://api.imgur.com/2/upload.xml", values);
         XDocument xDocument = XDocument.Load(new MemoryStream(response));
         return (string)xDocument.Root.Element("links").Element("original");
      }
   }
}

И собственно код самой программы:


public partial class ScreenForm : Form
   {
      Rectangle rect;
      Bitmap bmpScreenshot;
      //формат скриншотов
      ImageFormat imgFormat = ImageFormat.Png;

      public ScreenForm()
      {
         InitializeComponent()
         this.Paint += new System.Windows.Forms.PaintEventHandler(this.ScreenForms_Paint);
         this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ScreenForm_KeyDown);
         this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ScreenForm_MouseDown);
         this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ScreenForm_MouseMove);
         this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ScreenForm_MouseUp);
         this.FormBorderStyle = FormBorderStyle.None;
         this.ShowInTaskbar = false;
         this.TopMost = true;
         this.DoubleBuffered = true;
         this.Height = Screen.PrimaryScreen.Bounds.Height;
         this.Width = Screen.PrimaryScreen.Bounds.Width;
         //Указываем полученный ключ
         Uploader.IMGUR_KEY = "83dd0aacde6c6fc74d16638d5724bf96";
         MakeScreenShot();            
         this.BackgroundImage = (Image)bmpScreenshot;
         this.Cursor = Cursors.Cross;
      }
      protected override CreateParams CreateParams
      {
         get
         {
            CreateParams cp = base.CreateParams;
            cp.ExStyle /= 0x02000000;
            return cp;
         }
      }
      private void MakeScreenShot()
      {
         Graphics gfxScreenshot;
         bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, 
PixelFormat.Format32bppArgb);
         gfxScreenshot = Graphics.FromImage(bmpScreenshot);
         gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, 
Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
         gfxScreenshot.Dispose();
      }
      public Bitmap CropImage(Bitmap source, Rectangle section)
      {
         Bitmap bmp = new Bitmap(section.Width, section.Height);
         Graphics g = Graphics.FromImage(bmp);
         g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
         return bmp;
      }
      private void ScreenForms_Paint(object sender, PaintEventArgs e)
      {
         //цвет заливаемой области
         using (SolidBrush b = new SolidBrush(Color.FromArgb(75, 100, 100, 100)))
         {
            e.Graphics.FillRectangle(b, rect);
         }
      }
      private void ScreenForm_KeyDown(object sender, KeyEventArgs e)
      {
         if (e.KeyCode == Keys.Escape)
            base.Close();
      }
      private void ScreenForm_MouseDown(object sender, MouseEventArgs e)
      {
         if (e.Button == MouseButtons.Left)
         {
            rect = new Rectangle(e.X, e.Y, 0, 0);
         }
         else if (e.Button == MouseButtons.Right)
         {
            base.Close();
         }
      }
      private void ScreenForm_MouseMove(object sender, MouseEventArgs e)
      {
         if (e.Button == MouseButtons.Left)
         {
            rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
         }
         this.Invalidate();
      }
      private void ScreenForm_MouseUp(object sender, MouseEventArgs e)
      {
         this.Hide();
         //вырезаем выделенную область
         Bitmap croppedBmp = CropImage(bmpScreenshot, rect);
         //мне понадобилось указывать в углу  время скришнота, что и делаем
         StringFormat strFormat = new StringFormat();
         strFormat.Alignment = StringAlignment.Far;
         strFormat.LineAlignment = StringAlignment.Far;
         Graphics g = Graphics.FromImage(croppedBmp);
         g.DrawString(DateTime.Now.ToString(), new Font("Tahoma", 8), Brushes.Purple, new RectangleF
(0, 0, croppedBmp.Width,croppedBmp.Height), strFormat);
         //загрузка на сервер, копирование ссылки в буфер и открытие url картинки в браузере
         string link = Uploader.UploadToImgur(croppedBmp, imgFormat);
         Clipboard.SetText(link);
         Process.Start(link);
         Application.Exit();
      }
}

Что же получилось?

В результате имеем то, что хотели.
Простая быстрая программа, не делающая ничего лишнего.
image
Никаких мусорных временных файлов не создаётся.
Минимальная базовая функциональность, как готовое законченное решение
рассматривать пока рано.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.02.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Kaspersky Internet Security для всех устройств. 2-Device 1 year Base Download Pack
Advanced Data Export VCL Suite (with sources) + 1 Year Maintenance
Компонент NetworkLock - от 1 ПК до 24 ПК
Nero Basic Burning ROM 2018 VL 5 - 9 License corporate
Symantec Ghost Solution Suite, License, 1-24 Devices
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Каждый день новые драйверы для вашего компьютера!
ЕRP-Форум. Творческие дискуссии о системах автоматизации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Пишу программы на заказ для студентов (187)
Пишу для студентов на с, с++, паскаль в средах ms visual studio, qt, builder, borland c, delphi....
 
Пишу программы на заказ профессионально (2282)
Пишу программы на заказ на языках Pascal (численные методы, списки, деревья, прерывания) под...
 
Ищу программиста для написания программы (21)
Ищу программиста ,владеющего Вижуал Бэйсик и программированием в Экселе, для написания...
 
Настройка меню "Пуск" Windows 7 при помощи реестра (3)
Скажите пожалуйста, а как можно закрепить ярлыки программ с помощью твиков реестра в левой части...
 
Ищу программиста PYTHON (1)
Ищу программиста для написание программ python 3 + библиотека tkinter Есть данные в БД...
 
 
 



    
rambler's top100 Rambler's Top100