+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 92.51 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

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

08.02.2012 14:09
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
Никаких мусорных временных файлов не создаётся.
Минимальная базовая функциональность, как готовое законченное решение
рассматривать пока рано.

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

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям.

Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе.

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



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года