Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Bitmap

1.8K
17 марта 2004 года
neutrino4
94 / / 05.09.2003
Как можно получить содержимое из HBITMAP, не преобразовывая его к DIB?
527
17 марта 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by neutrino4
Как можно получить содержимое из HBITMAP, не преобразовывая его к DIB?



Чем не устраивает структура
typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP;

Получаемая функцией

BITMAP bitmap;
HBITMAP hBitmap;
int GetObject(
(HGDIOBJ)hBitmap,
sizeof(BITMAP),
&bitmap
);

1.8K
18 марта 2004 года
neutrino4
94 / / 05.09.2003
Вобщем-то, мне нужно каким-нибудь образом получить информацию о содержимом окна, причем в таком виде, чтобы ее можно было потом передать по сети и воспроизвести на другом компьтере. Насколько я понимаю, если использовать DIB, то это будет медленно, хотя может быть я ошибаюсь...
527
18 марта 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by neutrino4
Вобщем-то, мне нужно каким-нибудь образом получить информацию о содержимом окна, причем в таком виде, чтобы ее можно было потом передать по сети и воспроизвести на другом компьтере. Насколько я понимаю, если использовать DIB, то это будет медленно, хотя может быть я ошибаюсь...



Скорее проблемы со скоростью будут из-за передачи, так 1024x768x32 примерно 4Mb, а за функции не волнуйся - будут работать нормально.

1.8K
20 марта 2004 года
neutrino4
94 / / 05.09.2003
Может быть можно как-то определять изменившиеся части изображения и передавать только их? Это сэкономит трафик.
527
21 марта 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by neutrino4
Может быть можно как-то определять изменившиеся части изображения и передавать только их? Это сэкономит трафик.


Можно, но только обработка этого полностью ложиться на программу. Ведь не зря же в Windows есть функция InvalidateRect, которая помещает прямоугольник как требующий перерисовки. Однако я не знаю как быть с программами, которые получили постояный DC - что-то типа такого:
HDC hDC = ::GetDC(GetSafeHwnd());
И потом рисует там.
Так что по идее придется писать вроде этого:

class CScreenPart
{
CRect m_rcPart;
CBitmap m_bmPart;
};

class CMyWindow : public CWnd
{
CBitmap m_bmPrevScreen;
void GetChangedParts(CBitmap& bmNewScreen, CTypedPtrList<CPtrList, CScreenPart*>& list);

void SendChangedParts(CTypedPtrList<CPtrList, CScreenPart*>& list);

HBITMAP GetScreen(void);

void OnTimer(UINT)
{
CTypedPtrList<CPtrList, CScreenPart*> list;
CBitmap bmNewScreen(GetScreen());
GetChangedParts(bmNewScreen, list);
SendChangedParts(list);
m_bmPrevScreen.DeleteObject();
m_bmPrevScreen = bmNewScreen;
}
};

Правда скорее всего отсылать придется в отдельном потоке.

1.8K
28 марта 2004 года
neutrino4
94 / / 05.09.2003
HBITMAP, на сколько я понимаю можно получить с пом. CreateCompatibleBitmap только при создании контекста в памяти. Мне желательно на прямую без всяких промежуточных контекстов по контексту окна получить HBITMAP и потом соотв. BITMAP. Как это сделать?
527
28 марта 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by neutrino4
HBITMAP, на сколько я понимаю можно получить с пом. CreateCompatibleBitmap только при создании контекста в памяти. Мне желательно на прямую без всяких промежуточных контекстов по контексту окна получить HBITMAP и потом соотв. BITMAP. Как это сделать?


Не обязательно создавать каждый раз новую. Достаточно предусмотреть какое-то определенное деление, например, 16x16 частей, создать для каждой части bitmap и использовать их во время работы. Функция bitblt работает быстро, например, класс CImage использует один dc на все экземпляры и не создает каждый раз контекст в памяти, так что можно воспользоваться им.

1.8K
29 марта 2004 года
neutrino4
94 / / 05.09.2003
Благодарю за ответы, но дело в том, что я очень плохо знаю MFC, поэтому проще все делать на WinAPI (IMHO). Ваш пример я тоже не очень понял ввиду вышесказанного. На сколько я понимаю, дело обстоит так:
есть окно (десктоп в моем случае);
можно получить контекст этого окна;
нужно переслать содержимое этого окна по сети, его можно достать из структуры BITMAP, которую можно получить, имея HBITMAP;
соотв. HBITMAP получается только после CreateCompatibleBitmap (битовая карта для контекста в памяти);
соотв. единственный способ получить содержимое окна в готовом для передачи виде - создать контекст в памяти, создать для него битовую карту, использовать BitBlt вроде:
BitBlt(hMemDC,0,0,WND_WIDTH,WND_HEIGHT,hWndDC,0,0,..)
после этого, как вы сказали, использовать GetObject, чтобы получить BITMAP, который уже можно пересылать.
Непонятны две вещи:
1)можно ли избежать промежуточного контекста в памяти, и напрямую "выдирать" BITMAP из окна?
2)как на приемнике по имеющейся структуре BITMAP восстановить изображение в окне (какие функции)?
527
29 марта 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by neutrino4
Благодарю за ответы, но дело в том, что я очень плохо знаю MFC, поэтому проще все делать на WinAPI (IMHO). Ваш пример я тоже не очень понял ввиду вышесказанного. На сколько я понимаю, дело обстоит так:
есть окно (десктоп в моем случае);
можно получить контекст этого окна;
нужно переслать содержимое этого окна по сети, его можно достать из структуры BITMAP, которую можно получить, имея HBITMAP;
соотв. HBITMAP получается только после CreateCompatibleBitmap (битовая карта для контекста в памяти);
соотв. единственный способ получить содержимое окна в готовом для передачи виде - создать контекст в памяти, создать для него битовую карту, использовать BitBlt вроде:
BitBlt(hMemDC,0,0,WND_WIDTH,WND_HEIGHT,hWndDC,0,0,..)
после этого, как вы сказали, использовать GetObject, чтобы получить BITMAP, который уже можно пересылать.
Непонятны две вещи:
1)можно ли избежать промежуточного контекста в памяти, и напрямую "выдирать" BITMAP из окна?
2)как на приемнике по имеющейся структуре BITMAP восстановить изображение в окне (какие функции)?


1)не знаю, тут надо покопаться
2)надо передавать не структуру
typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP;
Так как указатель на удаленном компьютере ничего не даст, а данные из bmBits, размеры и т.д.

Создание нового DC - 64 кБайта из кучи GDI, так что не обращай внимание. Создай одну на всю программу копию экрана, передавай его изменившиеся части, затем на приемнике отображай переданные данные на экране с помощью BitBlt

1.8K
30 марта 2004 года
neutrino4
94 / / 05.09.2003
Цитата:
Так как указатель на удаленном компьютере ничего не даст, а данные из bmBits, размеры и т.д.


Это я понимаю :)

Цитата:
затем на приемнике отображай переданные данные на экране с помощью BitBlt


Да, но перед BitBlt надо как-то BITMAP и все, что с ним связано поместить в содержимое промежуточной поверхности приемника, короче обратная операция по отношению к GetObject на компе-источнике.
И еще, BITMAP, на сколько я понимаю, содержит информацию в формате Device Dependent Bitmap, а он зависит от конкретного устройства. Так вот, на сколько серьезно зависит? Различается от производителя к производителю или формат может быть различным даже в пределах карт от одной фирмы? Скажем, у меня на обоих компах nVidia, будет ли изображение адекватно воспроизводиться?

527
30 марта 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by neutrino4

Это я понимаю :)

Да, но перед BitBlt надо как-то BITMAP и все, что с ним связано поместить в содержимое промежуточной поверхности приемника, короче обратная операция по отношению к GetObject на компе-источнике.
И еще, BITMAP, на сколько я понимаю, содержит информацию в формате Device Dependent Bitmap, а он зависит от конкретного устройства. Так вот, на сколько серьезно зависит? Различается от производителя к производителю или формат может быть различным даже в пределах карт от одной фирмы? Скажем, у меня на обоих компах nVidia, будет ли изображение адекватно воспроизводиться?


Простой путь:
создаешь на приемнике одну bitmap такого же размера, при приеме данных копируешь bmBits и все.
Различия DC, влияющие на bitmap:
BITSPIXEL
PLANES
Для 24 бит это соответсвенно 8 и 3
Я обычно создаю буфер для отображения так
CImage m_iImage;
m_iImage.Create(cx, cy,
::GetDeviceCaps(hWindowDC, BITSPIXEL) * ::GetDeviceCaps(hWindowDC, PLANES))
При несовпадении форматов скорее всего будет просто аппроксимация изображения существующими цветами. Чтобы переделать в другой формат - функции GetDIBits, SetDIBits.

В общем я бы делал так:
Создаем массив
CImage m_2darrayParts[16][16];

Посылаем приемнику Image с двумя переменным i,j - индексы в массиве. Приемник вычисляет позицию на экране. С помощью функции Draw из CImage отображаем в соответствующую область.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог