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

Discussion in 'WASM.BEGINNERS' started by Aids, Dec 14, 2008.

  1. Aids

    Aids New Member

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

    Mikl___ Супермодератор Staff Member

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

    murder Member

    Blog Posts:
    0
    Joined:
    Jun 3, 2007
    Messages:
    628
    Так пиксели будут теряться.

    Лучше брать среднее арифметическое 4 пикселей.
    Для 32 битного изображения примерно так:
    Code (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

    Blog Posts:
    0
    Joined:
    Sep 29, 2005
    Messages:
    2,566
    Aids
    Мне нужно хранить мясо в холоде. Зачем мне покупать холодильник, если я не буду хранить в нём молоко?
    Ответ в том, что мясо тем не менее нужно где-то хранить.
    Мораль: создавайте контекст устройства, а не мучайте себя вопросами бытия. Создавайте не для того, чтобы вывести картинку на экран, а для того, чтобы её уменьшить.
     
  5. S_Alex

    S_Alex Alex

    Blog Posts:
    0
    Joined:
    Aug 27, 2004
    Messages:
    561
    Location:
    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

    Blog Posts:
    0
    Joined:
    Nov 30, 2007
    Messages:
    275
    l_inc
    Сделал следующее:
    Code (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

    Blog Posts:
    0
    Joined:
    Jan 31, 2004
    Messages:
    640
    Aids, поиск по форуму рулит..
    Я создавал аналогичный топик, и там много полезных постов..