Недавно при разработке xml web service возникла необходимость быстрой передачи изображения.
Разумеется, наиболее компактный способ ( помимо разных алгоритмов сжатия ) – работа с картинкой,
как с массивом байт. Класс Bitmap несёт много дополнительной информации и функциональности,
кроме того, он не сериализуется. Bitmap содержит в себе данные типа Color, которые занимают очень
много места( так как являются коллекцией цветов ). Если попытаться получить generic типа List <byte>
или List <int>, то при сериализации получится следующий XML
<unsignedint32>0000001<unsignedint32/>
То есть, очень большие теги, которые медленно передаются и разбираются. Аналогичная беда с ArrayList.
Так что остаётся byte[], который автоматически при передаче сериализуется в строку base64.
1. Самый тривиальный способ получения byte[] из Bitmap ( альфа-канал не важен )
i n t w i d t h = b m p . W i d t h ;
i n t h e i g h t = b m p . H e i g h t ;
i n t i = 0 ;
b y t e [ ] image = n e w b y t e [ w i d t h * h e i g h t * 3 ] ;
f o r ( i n t y = 0 ; y < h e i g h t ; y + + )
f o r ( i n t x = 0 ; x < w i d t h ; x + + )
{
image [ i ] = b m p . G e t P i x e l ( x , y ) . R ;
image[ i + + ] = b m p . G e t P i x e l ( x , y ) . G ;
image [ i + + ] = b m p . G e t P i x e l ( x , y ) . B ;
i + + ;
}
Он же – самый медленный.
2. Чтение потока из файла ( или БД при помощи G e t S q l B i n a r y ) . Несомненно, быстрее.
F i l e S t r e a m s t r e a m = n e w F i l e S t r e a m (
f i l e P a t h , F i l e M o d e . O p e n , F i l e A c c e s s . R e a d ) ;
B i n a r y R e a d e r r e a d e r = n e w B i n a r y R e a d e r ( s t r e a m ) ;
b y t e [ ] i m a g e = r e a d e r . R e a d B y t e s ( ( i n t ) s t r e a m . L e n g t h ) ;
r e a d e r . C l o s e ( ) ;
s t r e a m . C l o s e ( ) ;
Однако, при этом считывается вся мета-информация из начала файла, размер которой
не константа. То есть, при таком варианте в массиве содержится дополнительная информация,
зависящая от исходных данный и алгоритма сжатия.
3. И, наконец, последний вариант, здесь мы блокируем Bitmap в памяти, считываем
только данные изображения ( без метаинформации ).
S y s t e m . D r a w i n g . I m a g i n g . B i t m a p D a t a b d ;
R e c t a n g l e r e c t = n e w R e c t a n g l e ( 0 , 0 , b m p . W i d t h , b m p . H e i g h t ) ;
b d = b m p . L o c k B i t s (
r e c t ,
S y s t e m . D r a w i n g . I m a g i n g . I m a g e L o c k M o d e . R e a d W r i t e , S y s t e m . D r a w i n g . I m a g i n g . P i x e l F o r m a t . F o r m a t 2 4 b p p R g b ) ;
I n t P t r p t r = b d . S c a n 0 ;
i n t b y t e s = b m p . W i d t h * b m p . H e i g h t * 3 ;
b y t e [ ] r g b V a l u e s = n e w b y t e [ b y t e s ] ;
S y s t e m . R u n t i m e . I n t e r o p S e r v i c e s . M a r s h a l . C o p y ( p t r , r g b V a l u e s , 0 , b y t e s ) ;
b m p . U n l o c k B i t s ( b d ) ;