Помогите уменьшить BITMAP

Тема в разделе "WASM.BEGINNERS", создана пользователем Aids, 14 дек 2008.

  1. Aids

    Aids New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2007
    Сообщения:
    275
    Добрый день.
    Есть, например BITMAPINFOHEADER * pBIH;
    Есть указатель и массив байтов картинки (bmp) pBytes *pBt;
    Не могу разобраться, помогите советом. Мне надо изменить размер картинки, например уменьшить в 2 раза. По логике, такая операция сводится к копированию массива байтов из *pBt в новый массив, например в *pBt2, с определенным алгоритмом уменьшения кол-ва пикселей. Все что я нашел в MSDN это StretchBlt. В этой ф-ции надо получать HDC. Зачем мне получать HDC, если я не буду отображать картинку на экран, мне надо изменить размеры картинки и записать ее в файл.
    Как это сделать?
     
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.914
    Aids
    1) Создаешь файл и открываешь его
    2) Создаешь заголовок BMP, читаешь системную палитру и на ее основе создаешь палитру BMP
    3) читаешь из памяти и пишешь в файл через пиксель. В файле образ "перевернут", то есть придется писать в файл от конца к началу. Строки в BMP выравниваются до кратности 4
    4) закрываешь файл
     
  3. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Так пиксели будут теряться.

    Лучше брать среднее арифметическое 4 пикселей.
    Для 32 битного изображения примерно так:
    Код (Text):
    1. mov dx,height/2
    2. col:
    3. ;esi - исходный растр
    4. ;edi - результат
    5. mov ecx,width/2
    6. row:punpcklbw mm0,[esi]
    7.       psrlw mm0,8
    8.       punpcklbw mm1,[esi+4]
    9.       psrlw mm1,8
    10.       punpcklbw mm2,[esi+width*4]
    11.       psrlw mm2,8
    12.       punpcklbw mm3,[esi+width*4+4]
    13.       psrlw mm3,8
    14.       paddw mm0,mm1
    15.       paddw mm0,mm2
    16.       paddw mm0,mm3
    17.       psrlw  mm0,2
    18.       packuswb mm0,mm0
    19.       movd [edi],mm0
    20.       add esi,8
    21.       add edi,4
    22. loop row
    23. add esi,width*4
    24. dec dx
    25. jne col
    Код не проверял - возможно не работает
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Aids
    Мне нужно хранить мясо в холоде. Зачем мне покупать холодильник, если я не буду хранить в нём молоко?
    Ответ в том, что мясо тем не менее нужно где-то хранить.
    Мораль: создавайте контекст устройства, а не мучайте себя вопросами бытия. Создавайте не для того, чтобы вывести картинку на экран, а для того, чтобы её уменьшить.
     
  5. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    А я таким макаром делал.
    invoke CopyImage,[hBmp],IMAGE_BITMAP,[Width],[Height],LR_CREATEDIBSECTION
    -------------------------------------------------------------------
    The CopyImage function creates a new image (icon, cursor, or bitmap) and copies the attributes of the specified image to the new one. If necessary, the function stretches the bits to fit the desired size of the new image.

    HANDLE CopyImage(
    HANDLE hImage, // handle to the image to copy
    UINT uType, // type of image to copy
    int cxDesired, // desired width of new image
    int cyDesired, // desired height of new image
    UINT fuFlags // copy flags
    );
     
  6. Aids

    Aids New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2007
    Сообщения:
    275
    l_inc
    Сделал следующее:
    Код (Text):
    1.   if pGrabber=nil then exit;
    2.   pGrabber.GetCurrentBuffer(cbBuffer, nil);
    3.   pBuffer:=pointer(GlobalAlloc(0,cbBuffer));
    4.   hr:=pGrabber.GetCurrentBuffer(cbBuffer,pBuffer);
    5.   pGrabber.GetConnectedMediaType(mt);
    6.   pVih := mt.pbFormat;
    7.   hHeader.bmiHeader:=pVih^.bmiHeader;
    8.   hDispley:=GetDC(0);
    9.   hCopy:=CreateCompatibleDC(hDispley);
    10.   hBmp:=CreateCompatibleBitmap(hDispley,pVih^.bmiHeader.biWidth,pVih^.bmiHeader.biHeight);
    11.   SelectObject(hCopy,hBmp);
    12.   SetDIBitsToDevice(hCopy, 0, 0,pVih^.bmiHeader.biWidth, pVih^.bmiHeader.biHeight,0, 0,
    13.                                         0,pVih^.bmiHeader.biHeight,pBuffer,hHeader,DIB_RGB_COLORS);
    14.   stretchBlt(form1.Image1.Canvas.Handle,0,0,form1.Image1.Width,form1.Image1.Height,hCopy,
    15.                                         0,0,pVih^.bmiHeader.biWidth,pVih^.bmiHeader.biHeight,SRCCOPY);
    16.   DeleteDC(hDispley);
    17.   DeleteDC(hCopy);
    18.   DeleteObject(hBmp);
    19.   GlobalFree(dword(pBuffer));
    20.   Form1.Image1.Refresh;
    всё работает, но появилась проблема. У уменьшеной картинки сильно упало качество. Может что-то ещё посоветуете?
     
  7. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Aids, поиск по форуму рулит..
    Я создавал аналогичный топик, и там много полезных постов..