2014-01-08 7 views
1

Я видел статьи, демонстрирующие, что чернила могут быть сохранены с фоновым изображением, чтобы чернила накладывались на изображение, а затем сохранялись как один файл изображения , Но, к сожалению, статьи, которые я видел, не вдаются в подробности о том, как это делается. я могу сохранить фоновое изображение достаточно легко со следующим утверждением:InkPicture control - Как сохранить как чернила, так и изображение в файл изображения

axInkPicture1.Picture.Save(@"\path\to\file.gif"); 

... но нет чернил наслаивали на фоновое изображение

Я не знаю ни одного прямого метода, чтобы сохранить чернила, но это, как я сейчас делаю это:

string tempPath = Path.GetTempPath(); 
string tempFile = tempPath + @"\file.gif"; 
// save to a temp file 
if (axInkPicture1.Ink.Strokes.Count > 0) 
    { 
     byte[] bytes = (byte[])axInkPicture1.Ink.Save(InkPersistenceFormat.IPF_GIF, InkPersistenceCompressionMode.IPCM_Default); 

     using (MemoryStream ms = new MemoryStream(bytes)) 
     { 
      using (Bitmap gif = new Bitmap(ms)) 
      { 
       gif.Save(tempFile); 
      } 
     } 

    } 

Это экономит чернила, но нет фонового изображения.

Как сохранить как чернила, так и изображения в один файл?

Любая помощь или направление указательного ценится ...

### EDIT

Вот что еще я пытался до сих пор

InkRectangle inkBox = axInkPicture1.Ink.GetBoundingBox(); 
     byte[] gifbits = (byte[])axInkPicture1.Ink.Save(InkPersistenceFormat.IPF_GIF, InkPersistenceCompressionMode.IPCM_Default); 
     using (System.IO.MemoryStream buffer = new System.IO.MemoryStream(gifbits)) 
     using (var inkImage = new Bitmap(buffer)) 
     using (var picture = new Bitmap(axInkPicture1.Picture)) 
     using (var g = Graphics.FromImage(picture)) 
     { 
      g.DrawImage(inkImage, new Rectangle(inkBox.Left, inkBox.Right, axInkPicture1.Picture.Width, axInkPicture1.Height)); 
      picture.Save(tempFile, System.Drawing.Imaging.ImageFormat.Gif); 
     } 

... но я до сих пор не имея при удаче. Это сохраняет только фоновое изображение, а не чернила. Любые идеи, что я делаю неправильно?

Заранее спасибо

ответ

0

Тааак .... после того, как много битье головой и скрежет зубов, я, наконец, придумал решение моей проблемы, хотя, возможно, не решение, которое я ожидал, и, возможно, не самое лучшее решение , но он работает. Я новичок в мире C# и .net, поэтому, пожалуйста, не стесняйтесь меня исправить, если я укажу здесь что-то глупое.

То, что я обнаружил, было то, что код в моем правлении выше фактически работал, я просто не мог видеть чернила, потому что он находился за пределами прямоугольника. По-видимому, прямоугольники, полученные с использованием метода GetBoundingBox(), дают вам координаты inkSpace, которые значительно отличаются от координат пикселей.

Имея это в виду, моей следующей целью стало преобразование координат inkSpace в координаты пикселей с использованием метода inkSpaceToPixels. Я некоторое время боролся с этим и не мог понять, как это сделать, используя activex версию inkPicure или axInkPicture. Это потребовало некоторого обращения к hdcDisplay, которое я не мог полностью обвести вокруг себя.

В конце концов, я использовал версию .net (Microsoft.Ink) из Microsoft.Ink.dll. Единственная причина, по которой я использовал версию activeX для начала, заключалась в том, что по какой-то причине я не смог получить SDK для Windows Tablet PC для установки на мою машину разработки. Он продолжал жаловаться на то, что мне понадобилась ОС WinXP Tablet PC для ее установки. Я понял, что смог установить его на другой (Win7) ПК, а затем просто скопировать DLL с этого ПК.

Итак, вот окончательная версия, которая сейчас работает ... whew!

 //set the temporary file paths 
     string tempPath = Path.GetTempPath(); 
     string tempFile = tempPath + @"tmpFile.png"; 

     //get the bounding box and reference point for the ink strokes (in inkspace coordinates!) 
     Rectangle inkBox = inkPicture1.Ink.GetBoundingBox(); 
     Point point = new Point(inkBox.Left, inkBox.Top); 
     MessageBox.Show(point.X.ToString() + ", " + point.Y.ToString());//"before" coordinates 

     // Convert inkspace coordinates to pixel coordinates using Renderer 
     Graphics tempGraphics = CreateGraphics(); 
     Microsoft.Ink.Renderer inkRenderer = new Renderer(); 
     inkRenderer.InkSpaceToPixel(tempGraphics, ref point);; 
     MessageBox.Show(point.X.ToString() + ", " + point.Y.ToString());//"after" coordinates 
     // Clean up 
     tempGraphics.Dispose(); 

     // save the ink and background image to a temp file 
     if (inkPicture1.Ink.Strokes.Count > 0) 
     { 
      byte[] bytes = inkPicture1.Ink.Save(PersistenceFormat.Gif, CompressionMode.NoCompression); 
      using (MemoryStream ms = new MemoryStream(bytes)) 
      { 
       using (Bitmap gif = new Bitmap(ms)) 
       using (var bmp = new Bitmap(inkPicture1.BackgroundImage)) 
       using (var g = Graphics.FromImage(bmp)) 
       { 
        g.DrawImage(gif, new Rectangle(point.X, point.Y, gif.Width, gif.Height)); 
        bmp.Save(tempFile, System.Drawing.Imaging.ImageFormat.Png); 

       } 
      } 
     } 

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

0

Я думаю, у меня не хватает 50 репутации на комментарий, так что я буду отвечать на этот комментарий для других, которые могли бы приземлиться здесь после того, как поиск Google, как я сделал:

Это было очень полезно. Я перевел на VB, и это сработало.

Через некоторое верчение вокруг я нашел DLL по адресу:

C: \ Program Files (x86) \ Common Files \ Microsoft Shared \ Ink \ Microsoft.Ink.dll

Видимо я не только у одного есть проблема с поиском DLL, так как есть много записей google о том, как их получить - многие ошибаются, и большинство из них не так просто.

Если вы только начинаете с захватом подписи, не забудьте добавить фоновое изображение для контроля или потерпит неудачу на этой линии:

Использование BMP = New Bitmap (InkPicture1.BackgroundImage)

+0

Вскоре после того, как отправляя это решение, у меня возникли проблемы с файлом Microsoft.Ink.dll, который я использовал из SDK Tablet PC. Я нашел правильный путь к .dll, который вы указали выше, с помощью HansPassant. Вот ссылка [link.] (Http://stackoverflow.com/questions/21069420/visual-studio-2012-removes-inkpicture-control-every-time-i-open-my-project) – smitty1