Читать, обрабатывать и рисовать Bitmap

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Читать, обрабатывать и рисовать Bitmap

Сообщение IVAN008 » 08.12.2006 (Пт) 21:46

Надеюсь мой вопрос соответсвует правилам ..как там они .. ну которые я сурпулезно изучил вот! Если нет, прошу не гневаться :-)
Вопрос достаточно прост. Необходимо взять фото в формате .jpeg, скачать в массив информацию об изображении... кажется это называется Bitmap. и нарисовать полученный массив на .... ну пусть это будет PictureBox или ImageBox ... последнее даже лучче, там есть свойство Stech (кажеться непавильно, ну да ладно).
Когда я обращался год назад, мне великие гуру посоветовали использовать SetPixel и GetPixel. Теперь я целый год изучая мануал узнал про чудо функции GetBitmap и SetBitmap, так вот перавя читает нормально, а вот вторая рисует не правидлно... сбивается и не дорисовывает ничжнюю четветь рисунка, в массиве я проверял, все правильно.... кто встречал подобный глюк??

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

Сообщение tyomitch » 08.12.2006 (Пт) 21:48

Код покажи, а то у телепатов пятидневка -- сегодня они не работают.
Изображение

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 08.12.2006 (Пт) 21:54

Пока писал такой длинный пост, забыл о чем хотел спросить.... ну прошу извинить.... вечер уже мозги не работают как надо.... Так вот, черт с ними GetBitmapBit и Set....Bit ,
ВОПРОС: Можно ли читать Bitmap непосредственно из файла .jpeg, только без заморочек про кодирование этого саого жпег. Хочется просто - LoadBitmapBit file, array()

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 08.12.2006 (Пт) 22:00

Код полюбому не мой, это из примера скопировал, но в этом примере он как раз и не работает.


Код: Выделить всё
Private bmWidth As Long
Private bmHeight As Long
Private bmSize As Long
Private bmBits() As Byte

Private Sub cmdButton_Click()
     
    'Get picture's Width and Height
    bmWidth = Picture1.Width
    bmHeight = Picture1.Height

    'ReDefine Bit array to hold all pixels from picture box
    ReDim Bits(0 To 2, 0 To bmWidth - 1, 0 To bmHeight - 1) As Byte
   
    'Store size of bitmap in total pixels
    bmSize = 3 * bmWidth * bmHeight
   
    'Grab picture's pixels and load to Bit array
    GetBitmapBits Picture1.Image, bmSize, Bits(0, 0, 0)
   
    'Loop thru each Red, Green and Blue portion of each
    'pixel and turn it to it's negative color
    For Y = 0 To bmHeight - 1
        For X = 0 To bmWidth - 1
            Bits(2, X, Y) = 255 - Bits(2, X, Y) 'Red Bits
            Bits(1, X, Y) = 255 - Bits(1, X, Y) 'Green Bits
            Bits(0, X, Y) = 255 - Bits(0, X, Y) 'Blue Bits
        Next X
    Next Y
   
    'Load Bit array to picture box
    SetBitmapBits Picture1.Image, bmSize, Bits(0, 0, 0)
   
    'SetBitmapBits normally triggers a redraw event,
    'but just in case it doesn't, we'll do one now
    Picture1.Refresh
   
End Sub

w01fie
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 7
Зарегистрирован: 08.12.2006 (Пт) 19:31
Откуда: Russian Empire, Moscow

Сообщение w01fie » 08.12.2006 (Пт) 22:01

Я не совсем понял - почему нельзя JPEG отрисовать
Код: Выделить всё
Image1.Picture = LoadPicture("photo.jpg")?
··•··•••··•··••·•·•·•···••·•••··
C:\> per asper ad astra
684 Errare humanum est!
C:\>

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 08.12.2006 (Пт) 22:32

Ну можно его конечно и отрисовать, ... уж за год изучения мат.части, я делал это множество раз....
Но вопрос уважаемый W01fie, не в том,чтобы что-то отрисовать, а получить матрицу изображения и желательно тех размеров, которые... ну вообщем большие, а отрисовывается она уже меньшими размерами, ну или приходиться ее уменьшать, и методы "ВзятьПиксель" медленные и куча всего еще всего .....
Так вот возвращаемся к вопросу..... усли уж Винда распаковывает ЖПЕГ для его отображения в имже, нелья ли это дело перехватить и направить, так сказать в нужное русло...
Просьба не флудить

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

Сообщение tyomitch » 08.12.2006 (Пт) 22:44

IVAN008 писал(а):Код полюбому не мой, это из примера скопировал, но в этом примере он как раз и не работает.

Замечательно. Осталось поведать нам, что там внутри GetBitmapBits и SetBitmapBits.
Изображение

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

Сообщение BV » 08.12.2006 (Пт) 22:57

IVAN008 писал(а):ВОПРОС: Можно ли читать Bitmap непосредственно из файла .jpeg, только без заморочек про кодирование этого саого жпег. Хочется просто - LoadBitmapBit file, array()


Я не понял - тебе нужны не декодированные байты изображения из файла jpeg или все таки массив пикселей?
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;

w01fie
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 7
Зарегистрирован: 08.12.2006 (Пт) 19:31
Откуда: Russian Empire, Moscow

Сообщение w01fie » 09.12.2006 (Сб) 21:34

Короче - нужна библиотека по обработке ЖПЕГ - чтобы одной готовой функцией тебе файл превратила в матрицу пискселов? Тут без декодирования никак.... Или - можно из память веди считать (тока это не ко мне)...
··•··•••··•··••·•·•·•···••·•••··
C:\> per asper ad astra
684 Errare humanum est!
C:\>

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

Сообщение tyomitch » 10.12.2006 (Вс) 13:07

w01fie писал(а):Короче - нужна библиотека по обработке ЖПЕГ - чтобы одной готовой функцией тебе файл превратила в матрицу пискселов? Тут без декодирования никак.... Или - можно из память веди считать (тока это не ко мне)...

Библиотека по обработке ЖПЕГ, чтобы одной готовой функцией файл превратила в матрицу пискселов, уже есть в составе OLE. Именно ей пользуется LoadPicture. Почему она не устроила автора -- не знаю, скорее всего из-за того, что внутри его сверхсекретных функций GetBitmapBits и SetBitmapBits какие-нибудь баги.
Изображение

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

Сообщение BV » 10.12.2006 (Вс) 15:34

tyomitch,

Код: Выделить всё
Private Declare Function GetBitmapBits Lib "gdi32.dll" (ByVal hBitmap As Long, ByVal dwCount As Long, ByRef lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32.dll" (ByVal hBitmap As Long, ByVal dwCount As Long, ByRef lpBits As Any) As Long
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;

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

Сообщение tyomitch » 10.12.2006 (Вс) 15:58

Сорри: сутки пробыл в гостях, там нет ни VB, ни MSDN. :oops:

А у автора, в таком случае, наверняка проблема в строчке "bmSize = 3 * bmWidth * bmHeight", которая не учитывает пропуски между строчками картинки.
Изображение

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 11.12.2006 (Пн) 10:11

tyomitch писал(а):А у автора, в таком случае, наверняка проблема в строчке "bmSize = 3 * bmWidth * bmHeight", которая не учитывает пропуски между строчками картинки.

Хм... Ну не на четверть же...
Программисты не глючат - глючат компиляторы...

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 17.12.2006 (Вс) 13:58

ГЫ. был некоторое время без сети, и поэтому не успел ответить.... но ничего, ответов скопилось не мало, поэтому могу ответить всем сразу.
тАК вот....
Во-первых, мне надо получить массив ... байтовый массив, где элемент в четыре байта описывает один пиксель изображения. ну не знаю как еще яснее это выразить....
ДА!!! действительно известная 50% школьников функция LoadPicture, действительно берет файл и разкодировав его кладет в PictureBox или ImageBox, а мне уж очень хочеться, чтобы она положила его в мой массив imgArr(H,W,4) - где H - Height изображения, W - понятно, а 4 - количество байт описывающее один пиксель изображения (B,R,G,Res).
да, а кто знает что такое handle и нафига он нужен??

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

Сообщение tyomitch » 17.12.2006 (Вс) 17:59

GetDIBits поможет.
Пример находится поиском, только что проверил.
Изображение

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 17.12.2006 (Вс) 18:23

А фсё-таки приятно разговаривать с умными людьми!!!
Да и я уже росту!!! всего в трех постах умудрился объяснить что мне надо!!
Ну раз мы уже дошли до GetDIBits, тогда начнем новую череду вопросов!!
Вот описание сей причудливой функции:

GetDIBits
The GetDIBits function retrieves the bits of the specified compatible bitmap and copies them into a buffer as a DIB using the specified format.

int GetDIBits(
HDC hdc, // handle to DC
HBITMAP hbmp, // handle to bitmap
UINT uStartScan, // first scan line to set
UINT cScanLines, // number of scan lines to copy
LPVOID lpvBits, // array for bitmap bits
LPBITMAPINFO lpbi, // bitmap data buffer
UINT uUsage // RGB or palette index
);
Parameters
hdc
[in] Handle to the device context.
hbmp
[in] Handle to the bitmap. This must be a compatible bitmap (DDB).
uStartScan
[in] Specifies the first scan line to retrieve.
cScanLines
[in] Specifies the number of scan lines to retrieve.
lpvBits
[out] Pointer to a buffer to receive the bitmap data. If this parameter is NULL, the function passes the dimensions and format of the bitmap to the BITMAPINFO structure pointed to by the lpbi parameter.
lpbi
[in/out] Pointer to a BITMAPINFO structure that specifies the desired format for the DIB data.
uUsage
[in] Specifies the format of the bmiColors member of the BITMAPINFO structure. It must be one of the following values.

Гражане дорогие!!! что же такое этот коварный "handle", а что такое DC, и что такое DIB в фразе "copies them into a buffer as a DIB",
И если можно попроще, или ссылку на мануал где понятно для чайников написано.
Пример использования у меня есть, и достаточно навороченный, но я никак не могу понять, для чего нужен этот DC и .... ну и вообще.... нифига не понимаю.
Да чуть не забыл... special for tyomitch - вышеприведенные мной функции GetBitmapBits и ее омоним (кажеться так называются противоположности) - SetBitmapBit - являются функциями API из того же набора, что и Get/SetDIBits. Только в объявлении чуток попроще и вроде бы работать с ними, так же казалось попроще, однако они почему-то не работают - Get... делает что надо, а вот Set недодает треть в рисунок. Я в принципе об этом и спрашивал, а ты мне про телепатов....и ВПоиск.....
Вообще про поиск.... Господа умники!!! если знаешь что искать, то найти не проблема, а когда не знаешь, и пришел спросить, в надежде на помощь, а тебя посылают в Поиск - хочеться в ответ послать .... ну немного подальше....Не делайте так пожалуйста, это оч.Обидно бывает.

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 17.12.2006 (Вс) 18:30

tyomitch писал(а):А у автора, в таком случае, наверняка проблема в строчке "bmSize = 3 * bmWidth * bmHeight", которая не учитывает пропуски между строчками картинки.

Вот это если можно поподробнее.... ну про пропуски между строчками в картинки.
Какие пропуски бывают между строчками????
Или я один не умею читать в картинках между строчек????

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

Сообщение tyomitch » 17.12.2006 (Вс) 18:41

Читать между строк не нужно :-)

Каждая строка начинается с адреса, кратного 4.
Если ширина картинки не кратна 4, и в ней 3 байта на пиксел, то между строчками добавляется необходимый пропуск (от 1 до 3 байт).
Изображение

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 17.12.2006 (Вс) 18:48

Поставил 4 - не работает вовсе

IVAN008
Обычный пользователь
Обычный пользователь
 
Сообщения: 63
Зарегистрирован: 15.02.2005 (Вт) 12:19

Сообщение IVAN008 » 17.12.2006 (Вс) 18:56

надо еще заменть размерность массива, для приема четырех байт, а не трех, и поставить четыре... ну как сказал многоуважаемый tyomitch и тогда работает...
В принципе банальное решение банальной проблемы.
Спасибо всем за помощь :roll:
Special thanks FOR - tyomitch :D
Меня всегда поражало интуитивное чувствование проблемы.... ведь человек особо не вникал в вопрос...а сразу заподозрил, что между строк тоже читать надо

SGO
Обычный пользователь
Обычный пользователь
 
Сообщения: 86
Зарегистрирован: 08.01.2007 (Пн) 12:58

Сообщение SGO » 09.01.2007 (Вт) 14:19

У меня почти такая же проблема мне понравилась функция GetBitmapbits, но почему-то она (и SetBitmapbits тоже) у меня не работает (VB6), нужен какой-то компонент?

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

Сообщение Viper » 09.01.2007 (Вт) 15:09

Компонент никакой не нужен. показывай, как она у тебя не работает.
Весь мир матрица, а мы в нем потоки байтов!

SGO
Обычный пользователь
Обычный пользователь
 
Сообщения: 86
Зарегистрирован: 08.01.2007 (Пн) 12:58

Сообщение SGO » 09.01.2007 (Вт) 15:53

А никак не работает, выделяет GetBitmapBits и говорит Sub or Function not defined

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

Сообщение GSerg » 09.01.2007 (Вт) 15:58

Уууууу.......
SGO, сходи сюда и скачай API-Guide...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

SGO
Обычный пользователь
Обычный пользователь
 
Сообщения: 86
Зарегистрирован: 08.01.2007 (Пн) 12:58

Сообщение SGO » 09.01.2007 (Вт) 16:05

Кажется я понял почему... так понял эта функция в библиотеке и её надо декларировать?
(Private Declare Function GetBitmapBits...)

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

Сообщение tyomitch » 09.01.2007 (Вт) 20:48

Надо.
Изображение

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

Сообщение BV » 09.01.2007 (Вт) 20:54

2 SGO

Я бы просто скачал Win32API.tlb, очень удобно. Правда, не все там есть, кое что придется таки объявлять самому.
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;

lister
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 389
Зарегистрирован: 15.01.2005 (Сб) 7:34
Откуда: Страна оления

Сообщение lister » 09.01.2007 (Вт) 22:18

BV писал(а):Я бы просто скачал Win32API.tlb, очень удобно.

Ой, дайте ссылку, пожалуйста!!! [смайлик, стоящий на коленях]

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

Сообщение BV » 10.01.2007 (Ср) 0:56

Вот:
Вложения
win32.rar
(180.57 Кб) Скачиваний: 598
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;

lister
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 389
Зарегистрирован: 15.01.2005 (Сб) 7:34
Откуда: Страна оления

Сообщение lister » 10.01.2007 (Ср) 2:15

Спасибо большое!!! :P


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

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

Сейчас этот форум просматривают: SemrushBot и гости: 60

    TopList