Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > ListView, ImageList, Icons 16-bit


Автор: Alca 21.1.2013, 01:51
Как-то криво отображаются иконки при 16-битном системном цвете. Как пофиксить?
Кода много, поэтому выложу пока это, если необходим какой-то конкретный кусок,
то могу дописать.

Код

//  ImageList
list_images = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR16, 40, 80);

Код

/*
 * We use 32bpp images for menu. After these images are loaded from resources
 * the RGB values should be multiple to alpha to allow system to show ARGB
 * bitmaps correctly.
 */
HBITMAP 
pre_multiple_rgb(
    HBITMAP hsrc, 
    WORD    wBitsPixel
)
{
    HBITMAP hold = NULL;
    HDC hdcsrc = NULL;
    HDC hdc = GetDC(m_hMainDlg);
    BITMAPINFOHEADER bi;
    BITMAP bmp;
    BITMAPINFO bmi;
    HBITMAP dib = NULL;;
    UCHAR *dst = NULL;
    UCHAR *src, *tmp;
    UCHAR alpha;
    int bpl;
    ULONG x, y;
    DWORD bmp_size = 0;
    HANDLE hdib = NULL;
    char *lpbitmap = NULL;

    hdcsrc = CreateCompatibleDC(hdc);
    hold   = (HBITMAP)SelectObject(hdcsrc, hsrc);
    
    GetObject(hsrc, sizeof(BITMAP), &bmp);

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmp.bmWidth;;
    bi.biHeight = bmp.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = wBitsPixel;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    bmp_size = ((bmp.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp.bmHeight;
    hdib = GlobalAlloc(GHND, bmp_size);

    lpbitmap = (char *)GlobalLock(hdib);

    /* Get bits of source bitmap. */
    GetDIBits(hdcsrc, hsrc, 0, bmp.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS))

    /* For destination bitmap */
    bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
    bmi.bmiHeader.biWidth = bmp.bmWidth;
    bmi.bmiHeader.biHeight = bmp.bmHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = wBitsPixel;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = 0;
    bmi.bmiHeader.biXPelsPerMeter = 0;
    bmi.bmiHeader.biYPelsPerMeter = 0;
    bmi.bmiHeader.biClrUsed = 0;
    bmi.bmiHeader.biClrImportant = 0;

    dib = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&dst, NULL,    0);

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            alpha = tmp[3];

            dst[0] = tmp[0] * alpha / 255;
            dst[1] = tmp[1] * alpha / 255;
            dst[2] = tmp[2] * alpha / 255;
            dst[3] = alpha;

            dst += 4;
            tmp += 4;
        }
    }

stop_rgb:
    SelectObject(hdcsrc, hold);
    DeleteDC(hdcsrc);

    if (hdib) {
        GlobalUnlock(hdib);
        GlobalFree(hdib);
    }

    return dib;
}

Автор: Alca 21.1.2013, 04:48
http://stackoverflow.com/questions/632622/imagelist-transparency-on-listviews

Цитата

First up, ImageList_ReplaceIcon copies the icon data when adding it to an image list. So the HICON needs to be released afterwards.

Next, imagelists are natively bitmaps, not icons. And the way you are creating your imagelist makes the conversion of icon to bitmap very ambiguous. ILC_COLOR32 implies the imagelist should be created as a 32bit dib section, which typically contain transparency information via an embedded alpha channel. ILC_MASK instead implies that the internal bitmaps are DDB bitmaps, with the transparency information stored as a 1bpp mask bitmap.

The quickest solution to your problem - take your two icons:
Merge them into a single bitmap resource thats 32 pels wide by 16 high. Fill the background with a mask color :- purple or something.
Create the bitmap using ILC_COLOR|ILC_MASK
Load the bitmap being sure NOT to use LR_TRANSPARENT.
Add the bitmap using ImageList_AddMasked passing in a COLORREF that represents the mask color.

OR, for a better visual effect...
export your PNG data as a 32x16 32bpp bitmap file containing pre-multiplied alpha channel data.
Create the imagelist using the ILC_COLOR32 value.
LoadImage() with LR_CREATEDIBSECTION to load the bitmap as a 32bpp dib section.
Add the image using ImageList_Add()

(the last option is kind of tricky as the number of tools that support writing out 32bit bmp files with properly pre multiplied alpha channels is rather low).



Edited to add the following code sample. Using a 4bpp bitmap created in the dev environment this works just great :-
Код

HWND hwndCtl = CreateWindowEx(0,WC_LISTVIEW,TEXT("ListView1"),WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL,0,0,cx,cy,hWnd,(HMENU)101,hModule,NULL);
HBITMAP hbm = (HBITMAP)LoadImage(hModule,MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,0);
COLORREF crMask=RGB(255,0,255);
HIMAGELIST himl = ImageList_Create(16,16,ILC_COLOR|ILC_MASK,2,0);
ImageList_AddMasked(himl,hbm,crMask);
ListView_SetImageList(hwndCtl,himl,LVSIL_NORMAL);


Автор: feodorv 21.1.2013, 07:43
Так в чём суть-то? В том. что не нужно ILC_COLOR16, а нужно ILC_COLOR?

Автор: artsb 21.1.2013, 08:41
Цитата(Alca @  21.1.2013,  01:51 Найти цитируемый пост)
    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            alpha = tmp[3];
            dst[0] = tmp[0] * alpha / 255;
            dst[1] = tmp[1] * alpha / 255;
            dst[2] = tmp[2] * alpha / 255;
            dst[3] = alpha;
            dst += 4;
            tmp += 4;
        }
    }

Это не правильно, ИМХО. Вы преобразуете 32bit битмап в 16bit битмап. Вы подразучеваете, что 16bit битмапе тоже 4 байта для представления цвета. Но это не так - http://en.wikipedia.org/wiki/Color_depth#High_color_.2815.2F16-bit.29. Как следует из названия, там всего лишь 2 байта.

Автор: Alca 21.1.2013, 12:20
Цитата

Так в чём суть-то? В том. что не нужно ILC_COLOR16, а нужно ILC_COLOR?

нет,  в том, что надо юзать ImageList_AddMasked для прозрачности битмапа

artsb, так, что ли?
Код

        bpl = 2 * bmp.bmWidth; /* bytes per line */
        src = (UCHAR*)lpbitmap;
        for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
            tmp = src;
            for (x = 0; x < bmp.bmWidth; x++) {
                dst[0] = tmp[0];
                dst[1] = tmp[1];

                dst += 2;
                tmp += 2;
            }
        }



Значит, сделал как писал, использовал 2 байта + ImageList_AddMasked. 
Получилось!!
Спасибо всем.

Автор: artsb 21.1.2013, 13:36
Цитата(Alca @  21.1.2013,  12:20 Найти цитируемый пост)
artsb, так, что ли?

Неа.
Судя по Википедии, может быть три варианта:
Код

11111111 11111111
|  ||  | |  ||  |
\  /\  / \  /\  /
 r   g    b   a


11111111 11111111
|   ||    ||   ||
\   /\   /  \  /|
  r    g     b  a


11111111 11111111
|   ||     ||   |
\   /\    /  \  /
  r    g       b  

Какой из них используется в Винде я не знаю. Нужно покопаться.

Добавлено через 1 минуту и 10 секунд
Или реализовать все и посмотреть, какой из них будет работать  smile 

Автор: Alca 21.1.2013, 13:48
У меня так работает (16/32 bit):
Код

    if (16 >= wBitsPixel) {
        bpl = 4 * bmp.bmWidth; /* bytes per line */
        src = (UCHAR*)lpbitmap;
        for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
            tmp = src;
            for (x = 0; x < bmp.bmWidth; x++) {
                dst[0] = tmp[0];
                dst[1] = tmp[1];
                dst[2] = tmp[2];
                dst[3] = tmp[3];

                dst += 4;
                tmp += 4;
            }
        }
    } else {
        bpl = 4 * bmp.bmWidth; /* bytes per line */
        src = (UCHAR*)lpbitmap;
        for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
            tmp = src;
            for (x = 0; x < bmp.bmWidth; x++) {
                alpha = tmp[3];

                dst[0] = tmp[0] * alpha / 255;
                dst[1] = tmp[1] * alpha / 255;
                dst[2] = tmp[2] * alpha / 255;
                dst[3] = alpha;

                dst += 4;
                tmp += 4;
            }
        }
    }

Автор: artsb 21.1.2013, 14:24
Цитата(Alca @  21.1.2013,  13:48 Найти цитируемый пост)
У меня так работает (16/32 bit):

Странно... Я себе это представлял несколько иначе (для первого случая):
Код

    union UColor16bit
    {
        unsigned short Color; // 16bit
        struct
        {
            unsigned char Hi;
            unsigned char Low;
        } Parts;
        struct
        {
            unsigned short r: 4;
            unsigned short g: 4;
            unsigned short b: 4;
            unsigned short a: 4;
        } ARGB;
    };

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    UColor16bit cColor;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            cColor.Color = 0;
            
            cColor.ARGB.r = tmp[0] & 0xF;
            cColor.ARGB.g = tmp[1] & 0xF;
            cColor.ARGB.b = tmp[2] & 0xF;
            cColor.ARGB.a = tmp[3] & 0xF;
            
            dst[0] = cColor.Parts.Hi;
            dst[1] = cColor.Parts.Low;
            
            dst += 2; // 16bit
            tmp += 4;
        }
    }

Автор: Alca 21.1.2013, 14:31
Тестил на WinXP, Win2003 Server.
artsb, если честно, то я давно не кодил гуй на чистом WinAPI, 
может ты и правильно сдеалал

Автор: artsb 21.1.2013, 14:42
Цитата(Alca @  21.1.2013,  14:31 Найти цитируемый пост)
Тестил на WinXP, Win2003 Server.
artsb, если честно, то я давно не кодил гуй на чистом WinAPI, 
может ты и правильно сдеалал 

Может быть smile Просто ваш рабочий код рознится с описанием с Вики smile Ну, раз работает... Хотя, я бы разобрался )

Автор: Alca 21.1.2013, 14:50
Будет время - надо бы разобраться. 
Еще раз, спасибо.

Автор: Dem_max 23.1.2013, 06:45
А просто так не пробовал ???
Код

HICON hIcon = (HICON)LoadImage(hModule, szIcon, IMAGE_ICON, cx, cy, LR_CREATEDIBSECTION);
                                                           
himl = ImageList_Create(cx, cy, ILC_COLOR16 | ILC_MASK, 6, 0);
или так
himl = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, 6, 0);
ImageList_AddIcon(himl, hIcon);

без всяких байтомодификаций ???

Автор: Alca 23.1.2013, 11:20
Dem_max, в этом проекте есть свои нюансы, каждый битмап храниться в массиве.

Автор: Alca 4.2.2013, 22:49
Цитата

Код

    typedef union
    {
        unsigned short Color; // 16bit
        struct
        {
            unsigned char Hi;
            unsigned char Low;
        } Parts;
        struct
        {
            unsigned short r: 4;
            unsigned short g: 4;
            unsigned short b: 4;
            unsigned short a: 4;
        } ARGB;
    } UColor16bit;

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    UColor16bit cColor;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            cColor.Color = 0;

            cColor.ARGB.r = tmp[0] & 0xF;
            cColor.ARGB.g = tmp[1] & 0xF;
            cColor.ARGB.b = tmp[2] & 0xF;
            cColor.ARGB.a = tmp[3] & 0xF;

            dst[0] = cColor.Parts.Hi;
            dst[1] = cColor.Parts.Low;

            dst += 2; // 16bit
            tmp += 4;
        }
    }


Не работает!!

Автор: Alca 4.2.2013, 22:52
Цитата

Код

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = lpbitmap;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            if (wBitsPixel > 16) {
                alpha = tmp[3];

                dst[0] = tmp[0] * alpha / 255;
                dst[1] = tmp[1] * alpha / 255;
                dst[2] = tmp[2] * alpha / 255;
                dst[3] = alpha;
            } else {
                dst[0] = tmp[0];
                dst[1] = tmp[1];
                dst[2] = tmp[2];
                dst[3] = tmp[3];
            }

            dst += 4;
            tmp += 4;
        }
    }


Автор: Alca 4.2.2013, 22:53
Сама функция. Все эти скрины сделаны при 16 битном цвете.

Битмап так загружаю
Код

HBITMAP load_bitmap(UINT id)
{
    HBITMAP hbitmap = NULL;

    hbitmap = (HBITMAP)LoadImage(g_hInstance, MAKEINTRESOURCE(id),
            IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION |
            LR_LOADTRANSPARENT | LR_SHARED);
    if (!hbitmap) {
        logf_err("LoadImage failed with %ld\n", GetLastError());
        return NULL;
    }

    return pre_multiple_rgb(hbitmap, 32);
}

Автор: artsb 5.2.2013, 08:32
Alca, можете дать ваш тестовый проект, чтобы мне не катать сначала?

Автор: Alca 5.2.2013, 12:33
Цитата

тестовый проект

Попробую его для начала сделать

Автор: artsb 5.2.2013, 15:51
Alca, а так не пробовали:
Цитата

Create a bitmap with the desired color depth as the destination bitmap and copy the original image to it.

Взято отсюда: http://www.codeproject.com/Answers/129088/How-to-convert-a-bmp-of-32bppargb-to-a-bmp-of-16bp.aspx

Автор: Alca 5.2.2013, 17:18
Цитата

Попробую его для начала сделать

fail

Добавлено через 1 минуту и 47 секунд
Цитата

Create a bitmap with the desired color depth as the destination bitmap and copy the original image to it.

А где там код?

Автор: GremlinProg 5.2.2013, 17:24
Цитата(Alca @  5.2.2013,  19:18 Найти цитируемый пост)
А где там код?

А зачем он тебе? Просто загрузи 16-битный растр и скопируй его через BitBlt в 32-битный

Автор: artsb 5.2.2013, 17:29
Цитата(GremlinProg @  5.2.2013,  17:24 Найти цитируемый пост)
А зачем он тебе? Просто загрузи 16-битный растр и скопируй его через BitBlt в 32-битный 

ИМХО, наоборот smile

Автор: Alca 5.2.2013, 18:32
http://www.dreamincode.net/forums/topic/281612-how-to-make-bitmaps-on-menus-transparent-in-c-win32/

Код

HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc)
{
    HDC hdcSrc, hdcDst;
    HBITMAP hbmOld, hbmNew;
    BITMAP bm;
    COLORREF clrTP, clrBK;

    if ((hdcSrc = CreateCompatibleDC(NULL)) != NULL) {
        if ((hdcDst = CreateCompatibleDC(NULL)) != NULL) {
            int nRow, nCol;
            GetObject(hbmSrc, sizeof(bm), &bm);
            hbmOld = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
            hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, NULL);
            SelectObject(hdcDst, hbmNew);

                                
            BitBlt(hdcDst,0,0,bm.bmWidth, bm.bmHeight,hdcSrc,0,0,SRCCOPY);

            clrTP = GetPixel(hdcDst, 0, 0);// Get color of first pixel at 0,0
            clrBK = GetSysColor(COLOR_MENU);// Get the current background color of the menu

            for (nRow = 0; nRow < bm.bmHeight; nRow++)// work our way through all the pixels changing their color
                for (nCol = 0; nCol < bm.bmWidth; nCol++)// when we hit our set transparency color.
                    if (GetPixel(hdcDst, nCol, nRow) == clrTP)
                        SetPixel(hdcDst, nCol, nRow, clrBK);

            DeleteDC(hdcDst);
        }
        DeleteDC(hdcSrc);

    }
    return hbmNew;// return our transformed bitmap.
}



так??

Автор: artsb 5.2.2013, 18:54
По идее, так:
Код

HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc)
{
    HDC hdcSrc, hdcDst;
    HBITMAP hbmOldSrc, hbmOldDst, hbmNew;
    BITMAP bm;

    if ((hdcSrc = CreateCompatibleDC(NULL)) != NULL) {
        if ((hdcDst = CreateCompatibleDC(NULL)) != NULL) {
            GetObject(hbmSrc, sizeof(bm), &bm);
            hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
            hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, 8, NULL);
            hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew);
                                
            BitBlt(hdcDst,0,0,bm.bmWidth, bm.bmHeight,hdcSrc,0,0,SRCCOPY);

            SelectObject(hdcDst, hbmOldDst);
            DeleteDC(hdcDst);
            SelectObject(hdcSrc, hbmOldSrc);
        }
        DeleteDC(hdcSrc);
    }
    return hbmNew;// return our transformed bitmap.
}


Добавлено через 5 минут и 59 секунд
А! Понял смысл вашего перебора. По сути, да, у вас правильно. Только не забывайте восстанавливать старые битмапы. И, наверное, не стоит брать левый верхний пиксел, как цвет прозрачности. Проверяйте именно альфа-канал: если он равен 0, то заменяйте этот пиксел на свой цвет прозрачности, иначе - ничего не делайте. Но как мне кажется, лучше эту операцию проделать с исходным изображением ещё до BitBlt().

Автор: artsb 5.2.2013, 19:26
Только вот так:
Код

hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, 8, NULL);

Автор: Alca 5.2.2013, 23:56
да какая-то лажа с этой прозрачностью в 16 битном цвете  smile 

Автор: artsb 6.2.2013, 08:05
Попробую протестить. А что конкретно не так?

Автор: Alca 6.2.2013, 12:36
Цитата

Попробую протестить. А что конкретно не так?

http://forum.vingrad.ru/index.php?showtopic=348807&view=findpost&p=2546325

Автор: Alca 6.2.2013, 13:32
Желающим могу дать доступ через Team Viewer, в личку

Автор: artsb 6.2.2013, 15:01
А если так:
Код

HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc)
{
    HDC hdcSrc, hdcDst, dcScreen;
    HBITMAP hbmOldSrc, hbmOldDst, hbmNew = NULL;
    BITMAP bm;
    COLORREF clrTP, clrBK;

    dcScreen = GetDC(GetDesktopWindow());

    if ((hdcSrc = CreateCompatibleDC(dcScreen)) != NULL)
    {
        if ((hdcDst = CreateCompatibleDC(dcScreen)) != NULL)
        {
            int nRow, nCol;
            GetObject(hbmSrc, sizeof(bm), &bm);

            hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
//            hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, NULL);
            hbmNew = CreateCompatibleBitmap(dcScreen, bm.bmWidth, bm.bmHeight);

            if(hbmNew != NULL)
            {
                hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew);

                BitBlt(hdcDst,0,0,bm.bmWidth, bm.bmHeight,hdcSrc,0,0,SRCCOPY);

                clrTP = GetPixel(hdcDst, 0, 0);// Get color of first pixel at 0,0
                clrBK = GetSysColor(COLOR_MENU);// Get the current background color of the menu
                for (nRow = 0; nRow < bm.bmHeight; nRow++)// work our way through all the pixels changing their color
                {
                    for (nCol = 0; nCol < bm.bmWidth; nCol++)// when we hit our set transparency color.
                    {
                        if (GetPixel(hdcDst, nCol, nRow) == clrTP)
                        {
                            SetPixel(hdcDst, nCol, nRow, clrBK);
                        }
                    }
                }

                SelectObject(hdcDst, hbmOldDst);
                DeleteDC(hdcDst);
            }

            SelectObject(hdcSrc, hbmOldSrc);
        }
        DeleteDC(hdcSrc);
    }
    return hbmNew;// return our transformed bitmap.
}

Автор: Alca 6.2.2013, 15:11
Цитата

А если так:

ёптель, аллилуя, тока фон светло серый, видно, что отличается

Автор: artsb 6.2.2013, 15:18
Цитата(Alca @  6.2.2013,  15:11 Найти цитируемый пост)
тока фон светло серый

Ну это COLOR_MENU. Меняйте на цвет фона контрола. Останется только один косяк - когда итем выделен.

Автор: Alca 6.2.2013, 15:29
Цитата

Останется только один косяк - когда итем выделен.

Кстати, не замечал

Автор: artsb 6.2.2013, 15:33
Цитата(Alca @  6.2.2013,  15:29 Найти цитируемый пост)
Кстати, не замечал 

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

Автор: Alca 6.2.2013, 15:41
Цитата

Ну это COLOR_MENU. Меняйте на цвет фона контрола. 

А не меню???
На другой другой теме раб стола (упрощенной) все ок!

Автор: artsb 6.2.2013, 15:55
Цитата(Alca @  6.2.2013,  15:41 Найти цитируемый пост)
А не меню???
На другой другой теме раб стола (упрощенной) все ок! 

Я так понял, что у вас используется ListView. Вот его цвет и нужно брать.  По умолчанию это COLOR_WINDOW, вроде бы.

Автор: Alca 6.2.2013, 16:05
Цитата

Я так понял, что у вас используется ListView. Вот его цвет и нужно брать.  По умолчанию это COLOR_WINDOW, вроде бы.

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

Автор: Alca 8.2.2013, 11:56
Получил фидбек. Написали, что это грязный хак.  smile 

Автор: Alca 8.2.2013, 12:20
Цитата

Альфаканал и вырезать
все пикселы такого же цвета как левый верхний это разные вещи

Автор: artsb 8.2.2013, 20:53
Ясно. Нужно подумать как сделать.

Автор: Alca 12.2.2013, 15:27
ну его <пип>...

M
GremlinProg
Alca
 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)