Инвертировать картинку по X и Y если известен ее массив бит

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

Инвертировать картинку по X и Y если известен ее массив бит

Сообщение Mihail_ » 23.08.2009 (Вс) 23:22

Подскажите плиз, если есть массив бит, приведенный к такому же формута, как получаемый функцией getbitmapbits, то есть по 4 бита на пиксел [B] [G] [R] [0].
Как можно его быстро инвертировать по осям X и Y, чтобы получилось зеркальное изображение "вверх ногами"? :)
Вроде есть функкция StretchDIBits, но у нее как-то много не нужных в данном случае входных параметров, на выходе надо получить всего лишь массив - не рисуя его никуда.
И если вверх-ногами я еще худо-бедно могу перевернуть с циклом for - next, то отразить зеркально не получается.. Может быть как-то CopyMemory можно тут использовать?

Эксперты подскажите плиз :)
Заранее спасибо!


p.s. длина и ширина изображения нам известа - 240x320

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение iGrok » 24.08.2009 (Пн) 1:49

Ну вообще это получается просто "поворот" на 180 градусов.

Я немного не понимаю, в чём сложность с "зеркально", если "вверх ногами" получилось? Там, вроде, никаких особых отличий нет...
label:
cli
jmp label

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение Mihail_ » 24.08.2009 (Пн) 20:34

Ну вот не соображу как сделать.. Есть массив с байтами.. 1 пиксел 4 байта, в строке 320 пикселов

надо из картинки 1 получить картинку 2
Изображение


клинит на этом уже второй день.. не понимаю что надо с пикселами сделать.. помогите плиз(

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение Mihail_ » 24.08.2009 (Пн) 22:06

Я тут подготовил проект с перевернутым изображением, может кто посмотрит
Вложения
BitBITS.rar
(9.43 Кб) Скачиваний: 70

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение iGrok » 25.08.2009 (Вт) 0:58

Код: Выделить всё
...Удалено...


UPD: Там было много разных вариантов, но все они не работали. А потом я заглянул в MSDN, и офигел с кривости примера API-Guide.

Итак:
Код: Выделить всё
GetObject Picture1.Image, Len(PicInfo), PicInfo

'Во-первых у тебя криво выделяется буфер. Примерно в 9/4 больше, чем нужно.
'Косяк номер раз: 'BytesPerLine = (PicInfo.bmWidth * 3) + (PicInfo.bmWidth Mod 4)
'Косяк номер два: 'ReDim PicBits(0 To BytesPerLine * PicInfo.bmHeight * 3) As Byte

'Правильно:
ReDim nBuffer(0 To PicInfo.bmWidthBytes * PicInfo.bmHeight) As Byte
GetBitmapBits Picture1.Image, UBound(nBuffer), nBuffer(0)

'обработать байтовый массив nBuffer, чтобы изображение стало нормальным

'Ну а дальше всё просто. Этот вариант у меня был сначала, но из-за косяка с буфером он не работал - в видимую облась попадала только "чернота"
'из второй (бОльшей, 9/4 всё-таки) половины буфера, и картинка не отрисовывалась..
Dim arrLen As Long, t As Long
arrLen = UBound(nBuffer())
For i = 0 To arrLen \ 2 Step 4
    GetMem4 nBuffer(i), t
    GetMem4 nBuffer(arrLen - i - 4), nBuffer(i)
    PutMem4 nBuffer(arrLen - i - 4), t
Next i

SetBitmapBits Picture2.Image, UBound(nBuffer), nBuffer(0)


З.Ы. Это именно инверсия по X И Y. Если надо только по одной из осей - делается по другому.
label:
cli
jmp label

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение Mihail_ » 26.08.2009 (Ср) 20:18

спасибо, узнал о новых полезных низкоуровниевых функциях, только проект падает.. Как я понял потому что функции ожидают значения Long а у меня Byte :(
Вложения
BitBITS_n.zip
падающий проект с поправками
(23.65 Кб) Скачиваний: 51

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение iGrok » 26.08.2009 (Ср) 20:33

Блин. Так и знал, что нужно постить вместе с правильными объявлениями для этого случая...

Они не то, чтобы Long ожидают. Они ожидают указатель на данные, а ты им даёшь данные. Функция считает твои данные указателем, и пытается что-то прочитать по нему из памяти. Ессесно, у неё ничего не получается.
С твоим вариантом объявления GetMem / PutMem это должно выглядеть так:
Код: Выделить всё
    GetMem4 VarPtr(nBuffer(i)), VarPtr(t)
    GetMem4 VarPtr(nBuffer(arrLen - i - 4)), VarPtr(nBuffer(i))
    PutMem4 VarPtr(nBuffer(arrLen - i - 4)), t


Но можно взять другие объявления функций, и оставить как было. В архиве - вариант с исправленными объявлениями.
Вложения
BitBITS_n_fixed.zip
(23.91 Кб) Скачиваний: 45
label:
cli
jmp label

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение Mihail_ » 26.08.2009 (Ср) 21:36

спасибо большое!
правда по задумке надпись на картинке должна была все-таки читаться, но это я попробую решить - благо знаю теперь полезные низкоуровниевые функции :)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение iGrok » 26.08.2009 (Ср) 23:35

Ну я же говорил - это вариант именно "развернуть по X и Y".

По X:
Cоздаёшь буфер размером .bmWidthBytes.
Далее проходишь по массиву (For i = 0 to arrLen / 2 step .bmWidthBytes)
И копируешь содержимое точно также, как и в полном повороте картинки.
Только вместо t будет первый байт буфера (buff(0)), вместо 4 - .bmWidthBytes, а вместо GetMem / PutMem - CopyMemory.

Как-то так:
Код: Выделить всё
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
     ByRef Destination As Any, _
     ByRef Source As Any, _
     ByVal Length As Long)

...

Dim buff() As Byte, bLen As Long
bLen = PicInfo.bmWidthBytes
ReDim buff(0 To bLen) As Byte

For i = 0 To arrLen \ 2 Step bLen
    CopyMemory buff(0), nBuffer(i), bLen
    CopyMemory nBuffer(i), nBuffer(arrLen - i - bLen), bLen
    CopyMemory nBuffer(arrLen - i - bLen), buff(0), bLen
Next i


По Y несколько труднее. Тут уже надо подумать. =)
UPD:
Как-то так:
Код: Выделить всё
Dim j As Long, bLen As Long
bLen = PicInfo.bmWidthBytes

For i = 0 To arrLen - bLen + 1 Step bLen
    For j = 0 To bLen \ 2 Step 4
        GetMem4 nBuffer(i + j), t
        GetMem4 nBuffer(i + bLen - j - 4), nBuffer(i + j)
        PutMem4 nBuffer(i + bLen - j - 4), t
    Next j
Next i
label:
cli
jmp label

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

Re: Инвертировать картинку по X и Y если известен ее массив бит

Сообщение Mihail_ » 29.08.2009 (Сб) 22:51

огромное спасибо!

если кому потребуется конечный код, где на картинке читается текст, см. вложение
Вложения
BitBITS_done.rar
(20.88 Кб) Скачиваний: 80


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

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

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

    TopList