Параметры GetDiBits

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Параметры GetDiBits

Сообщение VB-constructor » 14.01.2007 (Вс) 22:34

Привет всем! Снова я)).... Снова работа с битмапом... на этот раз у меня не получается работа с GetDIBits, компилятор ругается за объявленную переменную BITMAPINFOHEADER, говорит ByRef argument type mismatch

несогласовывается((

Код: Выделить всё
Option Explicit
Private Const BI_RGB = 0&
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long

Private Type BITMAPINFOHEADER '40 bytes
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
End Type

Dim f As BITMAPINFOHEADER 

Dim Contain() As Byte

Private Sub Command1_Click()
    With f
        .biSize = LenB(f)
        .biWidth = ScaleX(Picture.Width, vbHimetric, vbPixels)
        .biHeight = ScaleY(Picture.Width, vbHimetric, vbPixels)
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = 0
        .biBitCount = 24
        .biCompression = BI_RGB
    End With
   
   
    ReDim Contain(1 To f.biWidth, 1 To f.biHeight) As Byte
    Command1.Caption = GetDIBits(hDC, Picture1.Picture, 0, f.biHeight, Contain(1, 1), f, 0)
   
End Sub


Подскажит, в чем незадача?

Спасибо
Последний раз редактировалось VB-constructor 14.01.2007 (Вс) 22:36, всего редактировалось 1 раз.
Человек рождён для того, чтобы достичь жизни...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.01.2007 (Вс) 22:36

Ну так переобъяви, делов-то...
Изображение

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 14.01.2007 (Вс) 22:40

Он у меня ругается на f в строчке:

Код: Выделить всё
Command1.Caption = GetDIBits(hDC, Picture1.Picture, 0, f.biHeight, Contain(1, 1), f, 0)


:idea: она вроде как объявлена:

Код: Выделить всё
Dim f As BITMAPINFOHEADER 


была...
Человек рождён для того, чтобы достичь жизни...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.01.2007 (Вс) 23:00

Ну правильно, а функция хочет BITMAPINFO. Какой вывод? :-)
Изображение

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 14.01.2007 (Вс) 23:18

ммм... :o снимаю шляпу...

и правда

она у меня не правильно объявлена что ли?..

я только что видел ее объявленную так: :
Код: Выделить всё
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFOHEADER, ByVal wUsage As Long) As Long


причем пример рабочий :roll
Человек рождён для того, чтобы достичь жизни...

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 14.01.2007 (Вс) 23:28

Объявлена правильно, а вот структуру не ту передаешь.
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 15.01.2007 (Пн) 0:05

BV, благодарю....

все, заменил....

вот только одно смущает: функция возвращает ноль ((
значит работает неправильно? что не так?

Код: Выделить всё
Option Explicit
Private Const BI_RGB = 0&

Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap _
As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI _
As BITMAPINFO, ByVal wUsage As Long) As Long

Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal _
x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As _
Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As _
Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Type BITMAPINFOHEADER '40 bytes
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
End Type

Dim f As BITMAPINFO  'структура битмап_инфо хранит _
информацию о копируемом рисунке, 40 байтов
Dim Contain() As Byte 'массив для битов рисунка
Private Type RGBQUAD
        rgbBlue As Byte
        rgbGreen As Byte
        rgbRed As Byte
        rgbReserved As Byte
End Type
Private Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
        bmiColors As RGBQUAD
End Type

Private Const DIB_RGB_COLORS = 0

Private Sub Command1_Click()
    With f.bmiHeader
        .biSize = LenB(f)
        .biWidth = ScaleX(Picture1.Picture.Width, vbHimetric, vbPixels)
        .biHeight = ScaleY(Picture1.Picture.Width, vbHimetric, vbPixels)
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = 0
        .biBitCount = 24
        .biCompression = BI_RGB
    End With
   
    ReDim Contain(1 To f.bmiHeader.biWidth, 1 To f.bmiHeader.biHeight) As Byte
    Command1.Caption = GetDIBits(hdc, Picture1.Picture, 0, f.bmiHeader.biHeight, Contain(1, 1), f, 0)

End Sub
Человек рождён для того, чтобы достичь жизни...

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 15.01.2007 (Пн) 0:46

Измени:

Код: Выделить всё
ReDim Contain(1 To 3, 1 To f.bmiHeader.biWidth, 1 To f.bmiHeader.biHeight) As Byte


И соответственно:

Код: Выделить всё
Command1.Caption = GetDIBits(hdc, Picture1.Picture, 0, f.bmiHeader.biHeight, Contain(1, 1, 1), f, 0)
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 15.01.2007 (Пн) 14:20

Good! Работает! Спасибо, BV!

Если я правильно понял, то здесь 1 to 3 - это по RGB на каждый пиксел... как в GetDiBits, только затычек нету
Человек рождён для того, чтобы достичь жизни...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.01.2007 (Пн) 15:05

Да есть там затычки :-|
Попробуй с картинкой, чей размер не кратен 4 -- увидишь.
Изображение

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 15.01.2007 (Пн) 16:26

Да вроде он и не кратен..., картинка копируется нормально...

А что я должен увидеть?
Человек рождён для того, чтобы достичь жизни...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.01.2007 (Пн) 17:40

"нормально" -- это ты по возвращаемому значению судишь, или как?
Изображение

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 15.01.2007 (Пн) 18:06

Я копирую эту картинку в массив байт с picture, а потом вставляюа на форму:

Код: Выделить всё
Option Explicit
Private Const BI_RGB = 0&

Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap _
As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI _
As BITMAPINFO, ByVal wUsage As Long) As Long

Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal _
x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As _
Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As _
Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Type BITMAPINFOHEADER '40 bytes
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
End Type

Dim f As BITMAPINFO  'структура битмап_инфо хранит _
информацию о копируемом рисунке, 40 байтов
Dim Contain() As Byte 'массив для битов рисунка

Private Type RGBQUAD
        rgbBlue As Byte
        rgbGreen As Byte
        rgbRed As Byte
        rgbReserved As Byte
End Type
Private Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
        bmiColors As RGBQUAD
End Type

Private Const DIB_RGB_COLORS = 0

Private Sub Command1_Click()
    With f.bmiHeader
        .biSize = LenB(f)
        .biWidth = ScaleX(Picture1.Picture.Width, vbHimetric, vbPixels)
        .biHeight = ScaleY(Picture1.Picture.Width, vbHimetric, vbPixels)
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = 0
        .biBitCount = 24
        .biCompression = BI_RGB
    End With
   
    ReDim Contain(1 To 3, 1 To f.bmiHeader.biWidth, 1 To f.bmiHeader.biHeight) As Byte

    Command1.Caption = GetDIBits(hdc, Picture1.Picture, 0, f.bmiHeader.biHeight, Contain(1, 1, 1), f, 0)
   
    SetDIBitsToDevice hdc, 0, 0, f.bmiHeader.biWidth, f.bmiHeader.biHeight, 0, 0, 0, _
    f.bmiHeader.biHeight, Contain(1, 1, 1), f, DIB_RGB_COLORS
   
End Sub


изображение копируется.............

это ж "нормально"?
Человек рождён для того, чтобы достичь жизни...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.01.2007 (Пн) 18:21

Естественно, что копируется нормально, потому что SetDIBitsToDevice рассчитывает, что в массиве затычки есть.
Вопрос в другом -- зачем ты копируешь картинку из одного hDC в другой через массив? Просто для интереса, или ты между GetDIBits и SetDIBitsToDevice рассчитываешь что-то делать с байтами этого массива?
Изображение

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 15.01.2007 (Пн) 19:43

или ты между GetDIBits и SetDIBitsToDevice рассчитываешь что-то делать с байтами этого массива?
рассчитываю, но сначала мне нужно понять саму суть их работы :) tyomitch, вопрос:
Да есть там затычки
ну по-видимому мы их или не объявили или они остались где-то за кадром :o
ReDim Contain(1 To 3, 1 To f.bmiHeader.biWidth, 1 To f.bmiHeader.biHeight) As Byte
это ж тоже самое, что f.bmiHeader.biWidth*f.bmiHeader.biHeight*3, а остатка от деления f.bmiHeader.biWidth нет вопрос: где его добавить?
Человек рождён для того, чтобы достичь жизни...

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 17.01.2007 (Ср) 21:55

И нужно ли?
Человек рождён для того, чтобы достичь жизни...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 18.01.2007 (Чт) 0:22

Тебе не удастся прочитать 24-битную картинку в трёхмерный массив байт, потому что в картинке есть затычки, а в массиве нет.
Изображение

Sofist
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 04.02.2007 (Вс) 19:19

Сообщение Sofist » 14.02.2007 (Ср) 13:06

Вопрос несколько не по теме, но затрагивает ее все равно.. Допустим имеем видео файл, который проигрывается в PictureBox1 с помощью MMControl. Потом нажимается пауза и дается команда на отработку вышеизложенного алгоритма. В результате массив Contain() получается забит нулями.. Я так понимаю функции GetDIBits передается hdc именно Picture1.Picture, а как передать ей hWnd от того же Picture1??

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.02.2007 (Ср) 13:11

Sofist, а каким образом это, по-твоему, поможет?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Sofist
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 04.02.2007 (Вс) 19:19

Сообщение Sofist » 14.02.2007 (Ср) 14:03

Вот так MMControl.hWndDisplay = Picture1.hWnd я заставляю видеофайл проигрываться в Picture1.. Самой фукнцкии я передаю Picture1.Picture и вот не знаю как через Picture1 связать видеофайл и функцию GetDIBits?? или с помощью этой функции я вообще не получу то, что хочу???

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.02.2007 (Ср) 14:08

Sofist писал(а):Самой фукнцкии я передаю Picture1.Picture

Не смущает, что в примере передаётся hdc, и что ничего кроме hdc туда не надо передавать?
Али свойства hdc у picturebox не нашёл? :neutral:
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Sofist
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 04.02.2007 (Вс) 19:19

Сообщение Sofist » 14.02.2007 (Ср) 14:52

Нашел.. а толку.. не понимаю куда мне его прописать.. GetDIBits(hdc, Picture1.hdc, 0, f.bmiHeader.biHeight, Contain(1, 1, 1), f, 0) - не работает.. GetDIBits(hdc, Picture1.Picture, 0, f.bmiHeader.biHeight, Contain(1, 1, 1), f, 0) - составляет массив из картинки находящейся в Picture1, а не видео, которое там проигрывается...

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 14.02.2007 (Ср) 15:12

вообще-то для hDC там одно только место - первый аргумент
Весь мир матрица, а мы в нем потоки байтов!

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.02.2007 (Ср) 15:23

Sofist писал(а):составляет массив из картинки находящейся в Picture1, а не видео, которое там проигрывается...

Вполне реально, что проигрывается оверлеем в коордниатах пикчербокса.
Это совершенно другой и гораздо более сложный вопрос.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Sofist
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 04.02.2007 (Вс) 19:19

Сообщение Sofist » 14.02.2007 (Ср) 15:25

Значит никак???

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 15.02.2007 (Чт) 0:55

Значит никак???
hdc - это, что относится к GDI, а видео - совсем другая история, но это не значит что не лья . Скриншоты же как-то делают. Насколько я понял, тееб нужно что-то подобное
Человек рождён для того, чтобы достичь жизни...

Sofist
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 04.02.2007 (Вс) 19:19

Сообщение Sofist » 16.02.2007 (Пт) 9:43

Мне нужно быстро загонять цвета пикселей в массив.. порядка 30 кадров в секунду...

X-hacker
Обычный пользователь
Обычный пользователь
 
Сообщения: 83
Зарегистрирован: 26.08.2006 (Сб) 1:22
Откуда: Moldova

Сообщение X-hacker » 17.02.2007 (Сб) 3:37

И что ты массивом будешь делать?Ето типа копирование видео через
PictureBox. Посто от того что ты планируешь сделать с полученным потоком много зависит...


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 102

    TopList