Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перетаскивание графического объекта на форму 
V
    Опции темы
JohnSparrow
Дата 4.4.2008, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 19.7.2006

Репутация: нет
Всего: нет



Доброго времени суток.

Необходимо предоставить пользователям возможность перетаскивать графические объекты в окно приложения (объекты из файлов Корела, Фотошопа, картинки из броузеров и т.д.). Пытаюсь получить изображение следующим образом:

Код

private void UserControl1_DragDrop(object sender, DragEventArgs e)
{
    IDataObject ido = e.Data;
    Image i;
    // считаем данные из dropped object
    if (ido.GetDataPresent(DataFormats.Dib))
    {
        MemoryStream ms = (MemoryStream)ido.GetData(DataFormats.Dib);
        i = Image.FromStream(ms);
    }
    ...
}



При выполнении i = Image.FromStream(ms); выбрасывается исключение "Недопустимый параметр". При этом MemoryStream из IDataObject для формата Dib возвращается нормальный (т.е. имеет ненулевой размер, данные из него можно вычитать и т.д.). Если же попробовать MemoryStream ms = (MemoryStream)ido.GetData(DataFormats.Bitmap), то возвращается null. Если кто в курсе, буду очень благодарен, поиск по форуму и гугл, к сожалению, не помогли, все описанные там варианты сводятся к этой комбинации.

Любопытно также, что при перетаскивании файла, когда ido.GetDataPresent("FileDrop") = true, легко получается создать экземпляр FileStream, загрузить в него данные по имени перетаскиваемого файла и т.д. Если же перетаскивать картинку из броузера, то для нее и ido.GetDataPresent(DataFormats.Dib) = true и ido.GetDataPresent("FileDrop") = true, но загрузить данные из файла через FileStream не удается, равно как и через MemoryStream.
PM MAIL   Вверх
PaZ1T1V
Дата 5.4.2008, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 169
Регистрация: 26.2.2008
Где: Багдад )

Репутация: нет
Всего: нет



помоему надо писать так, 

Код

            Image newImAge = new Bitmap(чего - то.Width, чего - то.Height);
            Graphics newGraphics = чего-то.CreateGraphics();
            newImAge = Image.FromStream(ms);


где, "чего-то" - это то, во что ты хо4еш переташить рисунок, например pictureBox

+          Image newImAge = new Bitmap(чего - то.Width, чего - то.Height);
            Graphics newGraphics = Graphics.FromImage(чего-то);
 
надо будет определить еще в конструкторе.
ну мб еще нужно будет молотком подправить
--------------------
[size=8]Atention please!!![/size]
[size=6]Кривые руки[/size]
PM MAIL WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
JohnSparrow
Дата 5.4.2008, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 19.7.2006

Репутация: нет
Всего: нет



Неет, если я получу экземпляр Image, то уж как-нибудь его отрисую, проблема в том, что операция Image i = Image.FromStream(ms) выбрасывает исключение. Короче говоря, не получается загрузить данные графического объекта в формате DIB из MemoryStream в Image.
PM MAIL   Вверх
mr.DUDA
Дата 5.4.2008, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 24
Всего: 232



Дело в том, что DIB это формат GDI, а по какой-то причине разработчики майкрософт не добавили аналог метода GDI+ создающего изображение из данных DIB в класс Image.

Вот хакерский способ обойти это:
Код
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("gdiplus.dll", SetLastError = true)]
        static extern int GdipCreateBitmapFromGdiDib(IntPtr bminfo, IntPtr pixdat, ref IntPtr image);

        private void Form1_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Dib))
                e.Effect = DragDropEffects.Copy;
        }

        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Dib))
            {
                // зачитываем данные картинки
                MemoryStream stream = (MemoryStream)e.Data.GetData(DataFormats.Dib);
                byte[] data = new BinaryReader(stream).ReadBytes((int)stream.Length);

                // воспользуемся GDI+ напрямую, чтобы создать картинку из DIB
                IntPtr bmInfo = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0);
                IntPtr pixData = Marshal.UnsafeAddrOfPinnedArrayElement(data, 40);
                IntPtr gdiPlusImage = IntPtr.Zero;
                GdipCreateBitmapFromGdiDib(bmInfo, pixData, ref gdiPlusImage);

                // создаём картинку-"пустышку" и приаттачиваем к зачитанной картинке GDI+
                Bitmap bmp = new Bitmap(1, 1);
                MethodInfo m = typeof(Image).GetMethod("SetNativeImage", BindingFlags.NonPublic | BindingFlags.Instance);
                m.Invoke(bmp, new object[] { gdiPlusImage} );

                // всё, можно пользоваться как обычным Bitmap-ом
                bmp.Save(@"c:\1.bmp", ImageFormat.Bmp);
            }
        }
    }
}



--------------------
user posted image
PM MAIL WWW   Вверх
JohnSparrow
Дата 5.4.2008, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 19.7.2006

Репутация: нет
Всего: нет



Большое спасибо, проблема преодолена. smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0570 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.