Битовый сдвиг

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

Битовый сдвиг

Сообщение VB-constructor » 13.01.2007 (Сб) 20:54

Привет всем!

Изучаю пример работы с GetBitmapBits и все достаточно прозрачно за исключением битового сдвига. Привожу полный листинг:

Код: Выделить всё
Option Explicit

'Create a new project, add a command button and a picture box to the project, load a picture into the picture box.
'Paste this code into Form1
Private Type BITMAP
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    bmBits As Long
End Type
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Dim PicBits() As Byte, PicInfo As BITMAP '14b
Dim Cnt As Long, BytesPerLine As Long


Private Sub Command1_Click()
    'KPD-Team 1999
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    'Get information (such as height and width) about the picturebox

        GetObject Picture1.Image, Len(PicInfo), PicInfo
        'reallocate storage space

        BytesPerLine = (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC

        ReDim PicBits(1 To BytesPerLine * PicInfo.bmHeight * 3) As Byte

        'Copy the bitmapbits to the array

        GetBitmapBits Picture1.Image, UBound(PicBits), PicBits(1)

        'Invert the bits
        For Cnt = 1 To UBound(PicBits)
            PicBits(Cnt) = 255 - PicBits(Cnt)
        Next Cnt
         'Set the bits back to the picture
        SetBitmapBits Picture1.Image, UBound(PicBits), PicBits(1)
        'refresh
        Picture1.Refresh

End Sub
но непонятен смысл двух строк:

Код: Выделить всё
        BytesPerLine = (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC

        ReDim PicBits(1 To BytesPerLine * PicInfo.bmHeight * 3) As Byte
По наитию ясно, что BytesPerLine определяют размер массива PicBits, но не понятно, чем руководствуются...

зачем PicInfo.bmWidth умножают на 3 и прибавляют... и откуда взято значение &HFFFFFFFC,

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

schalexey
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 18.02.2005 (Пт) 17:41
Откуда: Сургут

Сообщение schalexey » 13.01.2007 (Сб) 21:24

VB-constructor
FFFFFFFC = 11111111111111111111111111111100

Думаю можно предположить что получаем числов из старших разрядов, без первых двух. Эти два видать какую-то другую информацию несут вот и откидываем их.
3 видать это по количество цветов. 3 цвета => в 3 раза больше байт
а + 3 наверно какие то особенности связанные с bmWidth например на 1 меньше чем есть.

GM
programador
programador
 
Сообщения: 1427
Зарегистрирован: 24.06.2003 (Вт) 15:56
Откуда: 194.67.52.100

Сообщение GM » 14.01.2007 (Вс) 0:39

ИМХО выражение (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC делает следущее PicInfo.bmWidth * 3 - 1
الفيجوال بيسك الرابح

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

Сообщение tyomitch » 14.01.2007 (Вс) 1:42

Неужели опять? :roll:
http://bbs.vbstreets.ru/viewtopic.php?p=6644627#6644627

Нет, это не то же самое, что *3-1.
Изображение

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

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

Кажется немножко доходит. Получается, что картинка - это массив пикслов, каждый из которых размерностью 4 байта. (или все-таки 3, я не понял). Если три - то почему ее ширина должна быть кратна четырем и адрес каждой строки начинается с 4ех?

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


тогда смысл BytesPerLine = (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC по идее заключается в следующем: умножаем bmWidth на количество пустых строк, а потом еще зачем-то прибавляем 3(?), и добавляем 4байта без двух битов, тоже не совсем понятно...
Человек рождён для того, чтобы достичь жизни...

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

Сообщение tyomitch » 14.01.2007 (Вс) 14:33

VB-constructor писал(а):Кажется немножко доходит. Получается, что картинка - это массив пикслов, каждый из которых размерностью 4 байта. (или все-таки 3, я не понял). Если три - то почему ее ширина должна быть кратна четырем и адрес каждой строки начинается с 4ех?

Три. А так надо, видимо потому, что видеодрова так удобнее писать.

VB-constructor писал(а):тогда смысл BytesPerLine = (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC по идее заключается в следующем: умножаем bmWidth на количество пустых строк, а потом еще зачем-то прибавляем 3(?), и добавляем 4байта без двух битов, тоже не совсем понятно...

Неа, опять мимо. Ещё будут идеи? :-)
Изображение

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

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

Неа, опять мимо. Ещё будут идеи?
Не-а, больше ничего не приходит :(
Человек рождён для того, чтобы достичь жизни...

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

Сообщение tyomitch » 14.01.2007 (Вс) 16:27

Тогда хинт: вместо этой строчки можно написать "BytesPerLine = (PicInfo.bmWidth * 3) + (PicInfo.bmWidth Mod 4)".
Я обычно именно так и пишу, имхо это понятнее читающему, чем And.
Изображение

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

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

Я обычно именно так и пишу, имхо это понятнее читающему, чем And.
нды, еще бы... я б не за что не подумал, что это:
BytesPerLine = (PicInfo.bmWidth * 3) + (PicInfo.bmWidth Mod 4)".
и
BytesPerLine = (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC
являются одним и тем же...

так все понятно........ PicInfo.bmWidth Mod 4 - получаем количество строк и прибавляем PicInfo.bmWidth * 3 - то, что приходится на каждый пиксел))) Так ведь?
Я обычно именно так и пишу, имхо это понятнее читающему, чем And.
я тоже тперь так буду писать... спасибо, tyomitch!
Человек рождён для того, чтобы достичь жизни...

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

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

VB-constructor писал(а):так все понятно........ PicInfo.bmWidth Mod 4 - получаем количество строк и прибавляем PicInfo.bmWidth * 3 - то, что приходится на каждый пиксел))) Так ведь?

Нет. PicInfo.bmWidth Mod 4 -- это размер затычки между строками (от 0 до 3 байт).
Изображение

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

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

Нет. PicInfo.bmWidth Mod 4 -- это размер затычки между строками (от 0 до 3 байт).
А затычка - это и есть тот адрес, с котрого начинается строка? :o
Человек рождён для того, чтобы достичь жизни...

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

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

Нет. Затычка -- это просто пустое место. После неё начинается строка.
Изображение

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

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

ясно, tyomitch
большой спасибо за откровения!

И вот последний камень предкновения и последний вопрос: зачем нам затычка, пустое место в картинке? Какая его функция? Оно резервное для хранения какой-то информации
Человек рождён для того, чтобы достичь жизни...

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

Сообщение tyomitch » 15.01.2007 (Пн) 0:31

Исключительно затем, чтобы выровнять строки на адреса, кратные четырём. Ничего в этих дырках между строчками не хранится.
Изображение

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

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

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

schalexey
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 18.02.2005 (Пт) 17:41
Откуда: Сургут

Сообщение schalexey » 15.01.2007 (Пн) 14:23

VB-constructor выравнавание структуры эт, где размер ее должен быть кратен одному слову вроде (2байтам или размеру short int в Си).
Пошло из Си как раз, поэтому реальный размер структуры и тот что можем посчитать не редко различны.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.01.2007 (Пн) 22:48

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

кратен одному слову вроде (2байтам или размеру short int в Си).
А каков размер слова на IA-64?... :wink:
А я все практикую лечение травами...

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

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

Twister

Нет, выравнивание "эт, где" адреса членов структур кратны заданному числу...
если уж на то пошло, то зачем это делается?
Для меня эта информация нова, как первый снего и также неожиданна, как этот же снего, опавший в июле
:o
первое что приходит в глову:
Чтобы оставить промежутки между значениями адресов для заполнения данными?

P.S> Может есть статьи почитать по этому поводу?
Человек рождён для того, чтобы достичь жизни...

schalexey
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 18.02.2005 (Пт) 17:41
Откуда: Сургут

Сообщение schalexey » 16.01.2007 (Вт) 9:31

Twister
размер IA64 не знаю ) но знаю точно что размер short int 2 байта.
VB-constructor
Вот про выравнивание много написано: http://forum.sources.ru/index.php?showtopic=110906

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

Сообщение VB-constructor » 16.01.2007 (Вт) 21:33

schalexey
благодарю за ссылку. Весьма познавательное чтиво )
Человек рождён для того, чтобы достичь жизни...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 17.01.2007 (Ср) 1:06

размер IA64 не знаю
Это не структура, размера у нее, следовательно, нет... :lol:
А я все практикую лечение травами...

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

Сообщение tyomitch » 17.01.2007 (Ср) 11:11

Массив пикселей тоже не структура :roll:
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 17.01.2007 (Ср) 18:10

tyomitch писал(а):Массив пикселей тоже не структура :roll:
Ну если ты решил подловить меня на словах, то зря. :wink: Я не имел ввиду, что то, что не является структурой не имеет размера... :roll: Хотя и массив можно рассматривать как структуру, но это уже риторический вопрос...
А я все практикую лечение травами...

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

Сообщение tyomitch » 17.01.2007 (Ср) 18:33

Нет, я не о том.
Я о том, что статья о выравнивании структур имеет весьма слабое отношение к выравниванию пикселей в строке, о котором шла речь.
Изображение

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

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

Я о том, что статья о выравнивании структур имеет весьма слабое отношение к выравниванию пикселей в строке, о котором шла речь.
а чем отличается выравнивание пикселей в строке от выранивания структуры?
Человек рождён для того, чтобы достичь жизни...

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

Сообщение tyomitch » 17.01.2007 (Ср) 21:52

Тем, что пиксели не выравниваются. Только строки выравниваются.
Изображение

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

Сообщение BV » 17.01.2007 (Ср) 22:02

tyomitch, закажи у ANDLL схемку строк, и всем все станет понятно :)
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;


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

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

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 95

    TopList