Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сравнение попиксельно зоны раб. стола с указ. *bmp 
:(
    Опции темы
Travolta
Дата 27.11.2008, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 3.11.2008

Репутация: нет
Всего: нет



День добрый.
Мне надо сравнить заданную зону(область) рабочего стола попиксельно с 
указанным *.bmp файлом.
Опишите пожалуйста алгоритм при котором можно произвести эту процедуру.
Желатьно с использованием ключевых операторов.
Спасибо.
PM MAIL   Вверх
diadiavova
Дата 27.11.2008, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Можно создать битмап, скопировать в него нужную часть экрана и сравнивать попмксельно два битмапа
Примерно так
Код

Bitmap bm = new Bitmap();
Graphics g = Graphics.FromImage(bm);
g.CopyFromScreen(...здесь параметры...);



И дальш bm сравнивать с образцом. Едимственная оговорка, при создании битмапа конструктор возможно прийдётся использовать другой, чтобы формат пикселя не отличался от от того, с которым картинка будет сравниваться.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
jonie
Дата 28.11.2008, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



скорость сравнения в GDI+ будет ужасной...
можно чуток ускорить.. варианты есть, например подсчет хеш суммы или игры с non-managed GDI....
вариант 2 (откуда-то честно сперт):
Код

/////////////////////////////////////////////////////////////////////////////
//
//  CompareBitmaps
//    Compares two HBITMAPs to see if they contain the same image
//
//  Parameters :
//    HBitmapLeft  [in] : The HBITMAP handles that are to be compared
//    HBitmapRight [in] :
//
//  Returns :
//    true if the bitmaps are the same
//    false if they are different
//
/////////////////////////////////////////////////////////////////////////////


bool CompareBitmaps(HBITMAP HBitmapLeft, HBITMAP HBitmapRight)
{
    if (HBitmapLeft == HBitmapRight)
    {
        return true;
    }

    if (NULL == HBitmapLeft || NULL == HBitmapRight)
    {
        return false;
    }

    bool bSame = false;

    HDC hdc = GetDC(NULL);
    BITMAPINFO BitmapInfoLeft = {0};
    BITMAPINFO BitmapInfoRight = {0};

    BitmapInfoLeft.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    BitmapInfoRight.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    if (0 != GetDIBits(hdc, HBitmapLeft, 0, 0, NULL, &BitmapInfoLeft, DIB_RGB_COLORS) &&
        0 != GetDIBits(hdc, HBitmapRight, 0, 0, NULL, &BitmapInfoRight, DIB_RGB_COLORS))
    {
        // Compare the BITMAPINFOHEADERs of the two bitmaps

        if (0 == memcmp(&BitmapInfoLeft.bmiHeader, &BitmapInfoRight.bmiHeader, 
            sizeof(BITMAPINFOHEADER)))
        {
            // The BITMAPINFOHEADERs are the same so now compare the actual bitmap bits

            BYTE *pLeftBits = new BYTE<BitmapInfoLeft.bmiHeader.biSizeImage>;
            BYTE *pRightBits = new BYTE<BitmapInfoRight.bmiHeader.biSizeImage>;
            BYTE *pByteLeft = NULL;
            BYTE *pByteRight = NULL;

            PBITMAPINFO pBitmapInfoLeft = &BitmapInfoLeft;
            PBITMAPINFO pBitmapInfoRight = &BitmapInfoRight;

            // calculate the size in BYTEs of the additional

            // memory needed for the bmiColor table

            int AdditionalMemory = 0;
            switch (BitmapInfoLeft.bmiHeader.biBitCount)
            {
            case 1:
                AdditionalMemory = 1 * sizeof(RGBQUAD);
                break;
            case 4:
                AdditionalMemory = 15 * sizeof(RGBQUAD);
                break;
            case 8:
                AdditionalMemory = 255 * sizeof(RGBQUAD);
                break;
            case 16:
            case 32:
                AdditionalMemory = 2 * sizeof(RGBQUAD);
            }

            if (AdditionalMemory)
            {
                // we have to allocate room for the bmiColor table that will be

                // attached to our BITMAPINFO variables

                pByteLeft = new BYTE[sizeof(BITMAPINFO) + AdditionalMemory];
                if (pByteLeft)
                {
                    memset(pByteLeft, 0, sizeof(BITMAPINFO) + AdditionalMemory);
                    memcpy(pByteLeft, pBitmapInfoLeft, sizeof(BITMAPINFO));
                    pBitmapInfoLeft = (PBITMAPINFO)pByteLeft;
                }

                pByteRight = new BYTE[sizeof(BITMAPINFO) + AdditionalMemory];
                if (pByteRight)
                {
                    memset(pByteRight, 0, sizeof(BITMAPINFO) + AdditionalMemory);
                    memcpy(pByteRight, pBitmapInfoRight, sizeof(BITMAPINFO));
                    pBitmapInfoRight = (PBITMAPINFO)pByteRight;
                }
            }

            if (pLeftBits && pRightBits && pBitmapInfoLeft && pBitmapInfoRight)
            {
                // zero out the bitmap bit buffers

                memset(pLeftBits, 0, BitmapInfoLeft.bmiHeader.biSizeImage);
                memset(pRightBits, 0, BitmapInfoRight.bmiHeader.biSizeImage);

                // fill the bit buffers with the actual bitmap bits

                if (0 != GetDIBits(hdc, HBitmapLeft, 0, 
                    pBitmapInfoLeft->bmiHeader.biHeight, pLeftBits, pBitmapInfoLeft, 
                    DIB_RGB_COLORS) && 0 != GetDIBits(hdc, HBitmapRight, 0, 
                    pBitmapInfoRight->bmiHeader.biHeight, pRightBits, pBitmapInfoRight, 
                    DIB_RGB_COLORS))
                {
                    // compare the actual bitmap bits of the two bitmaps

                    bSame = 0 == memcmp(pLeftBits, pRightBits, 
                        pBitmapInfoLeft->bmiHeader.biSizeImage);
                }
            }

            // clean up

            delete[] pLeftBits;
            delete[] pRightBits;
            delete[] pByteLeft;
            delete[] pByteRight;
        }
    }

    ReleaseDC(NULL, hdc);

    return bSame;
}





--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Travolta
Дата 28.11.2008, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 3.11.2008

Репутация: нет
Всего: нет



diadiavova и jonie спасибо.

я стормозил. пишу на VС++.

jonie у меня        BYTE *pLeftBits = new BYTE<BitmapInfoLeft.bmiHeader.biSizeImage>;

эта строка и ей подобные выдаёт ошибку c:\documents and settings\duke\мои документы\visual studio projects\first2\first2.cpp(309): error C2446: '<' : no conversion from 'DWORD' to 'BYTE *'


как быть?

и ещё, извините за наглость, но всё же как скопировать зону экрана для данного случая ?
PM MAIL   Вверх
jonie
Дата 30.11.2008, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



Цитата

Код

BYTE *pLeftBits = new BYTE<BitmapInfoLeft.bmiHeader.biSizeImage>;

это че за новомодный синтаксис такой ?


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Travolta
Дата 30.11.2008, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 3.11.2008

Репутация: нет
Всего: нет



ЭЭ.

Так это ж вроде из кода, который ты привёл.
PM MAIL   Вверх
Zakonnic
Дата 1.12.2008, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 25.4.2006

Репутация: 2
Всего: 6



LockBits - штука как раз для таких случаев. Нууу... попробуйте создать отдельный проект с unsafe-методами и вставить что-то вроде этого:

Код

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace Utils
{
    public class MagicFeatures
    {
        unsafe public static bool CompareBmp(Bitmap bmp1, Bitmap bmp2, Rectangle rect)
        {   
            int width, height;
            width = rect.Width;
            height = rect.Height;
            int stride;
            PixelFormat pxl = bmp1.PixelFormat;

            BitmapData bmpData = bmp1.LockBits(rect, ImageLockMode.ReadOnly, pxl);
            IntPtr ptr = bmpData.Scan0;
            stride = bmpData.Stride;
            int offset = stride - 3 * width;
            int numbytes = width * (height) * 3 + offset * height;

            byte* bt1 = (byte*)ptr.ToPointer();

            // Далее фигарите такую же штуку для второго битмапа и сравниваете 
            // массивы побайтно (каждые 3 байта = RGB = 1 пиксель)

            // ...

         }

Чтобы код скомпилился, в свойсвах проекта надо разрешить ансейф-код. Потом можно получить битмап способом diadiavova и сравнить его с вашим, вызвав
bool result = Utils.MagicFeatures.CompareBmp(bmp1, bmp2, new Rectangle([координаты и размеры]));

ЗЫ. Код скопирован и слегка подправлен - если в таком виде не работает... ну придумайте что нибудь smile
 

Это сообщение отредактировал(а) Zakonnic - 1.12.2008, 12:37
--------------------
...и никогда не пишите в комментариях правду
PM MAIL ICQ   Вверх
Travolta
Дата 2.12.2008, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 3.11.2008

Репутация: нет
Всего: нет



Zakonnic

Спасибо тебе за уделённое время.
Буду разбираться (для VC++)

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0928 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.