Перевод кода

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Перевод кода

Сообщение AnarchyMob » 09.12.2008 21:26:15

Здравствуйте, помогите пожалуйста с таким вопросом, я пишу программу на Free Pascal и мне понадобилось в этой программе использовать функцию которая написана на C++. Вот собственно код (конвертация RGB to Grayscale)

Код: Выделить всё
void Paint()
{
    COLORREF *pvbits;

    pvbits = (COLORREF *)malloc(240*240*4); //массив пикселей изображения

    for (int j=0; j<240; j++) //конвертируем все пиксели изображения из цветных в grayscale
    {
        for (int i=0; i<240; i++)
        {
            BYTE* pPixel = (BYTE *)(&pvbits[i+240*j]);
            int rgb = ((11*pPixel[0]+30*pPixel[2]+59*pPixel[1])/100);
            pPixel[0]=rgb;
            pPixel[1]=rgb;
            pPixel[2]=rgb;
        }
    }
    free(pvbits);
}


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

P.S.
Кому нужно даю весь код:

Код: Выделить всё
void onPaint(HWND hWnd)
{
    HGDIOBJ bmp, oldbmp;
    HDC hdc, hdc2, ScreenDC;
    PAINTSTRUCT ps;
    BITMAPINFO bmi;
    COLORREF *pvbits;

    pvbits = (COLORREF *)malloc(240*240*4); //массив пикселей изображения
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); //создаем структуру, хранящую данные об изображении
    bmi.bmiHeader.biHeight = 240;
    bmi.bmiHeader.biWidth = 240;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage=0;
    bmi.bmiHeader.biClrUsed=0;
    bmi.bmiHeader.biClrImportant=0;

    hdc = BeginPaint(hWnd, &ps);

    ScreenDC = GetDC(0);

    hdc2 = CreateCompatibleDC(NULL);

    bmp = CreateDIBSection(hdc2, &bmi, DIB_RGB_COLORS, (VOID **)&pvbits, NULL, 0x0);
    oldbmp = SelectObject(hdc2, bmp);
    BitBlt(hdc2, 0, 0, 240, 240, ScreenDC, 0, 0, SRCCOPY);

    for (int j=0; j<240; j++) //конвертируем все пиксели изображения из цветных в grayscale
    {
        for (int i=0; i<240; i++)
        {
            BYTE* pPixel = (BYTE *)(&pvbits[i+240*j]);
            int rgb = ((11*pPixel[0]+30*pPixel[2]+59*pPixel[1])/100);
            pPixel[0]=rgb;
            pPixel[1]=rgb;
            pPixel[2]=rgb;
        }
    }

    BitBlt(hdc, 0, 0, 240, 240, hdc2, 0, 0, SRCCOPY); //выводим полученное на экран

    EndPaint(hWnd, &ps);

    SelectObject(hdc2, oldbmp);
    DeleteDC(hdc2);
    DeleteObject(bmp);
    ReleaseDC(hWnd, ScreenDC);

    free(pvbits);
}
AnarchyMob
новенький
 
Сообщения: 13
Зарегистрирован: 16.11.2008 23:44:36

Re: Перевод кода

Сообщение Sergei I. Gorelkin » 09.12.2008 22:36:42

Какой-то больной на всю голову код. Первый раз в жизни вижу, чтобы в обработчике OnPaint с экрана читали, вместо того чтобы туда писать. Кроме того, CreateDIBSection сама выделяет память под картинку, поэтому malloc в начале и free в конце совершенно не нужны (как оно с ними не падает и не съедает всю память - не понимаю).

А вообще то, что внути цикла, будет выглядеть вот так (на диалекте Free Pascal - Delphi такое не поймет):
Код: Выделить всё
var
  pPixel: PByte;
  pvbits: PCardinal;
  rgb: Integer;

...   

  pPixel := PByte(@pvbits[i+240*j]);
  rgb := ((11*pPixel[0]+30*pPixel[2]+59*pPixel[1]) div 100);
  pPixel[0]:=rgb;
  pPixel[1]:=rgb;
  pPixel[2]:=rgb;
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Перевод кода

Сообщение AnarchyMob » 09.12.2008 23:58:50

Большое спасибо! Согласен, код какой-то странный. Я сей код компилировал в PellesC работает вроде нормально, но памяти сколько потребляет я не посмотрел. И еще, я пишу в Lazarus, но всё-таки интересно что в вашем коде не поймёт Delphi?

P.S.
Возник еще вопросик. Как например если я в основном пишу с использованием синтаксиса Delphi (директива {$mode delphi}) написать часть кода или функцию (в рамках одного модуля) с использованием синтаксиса Free Pascal (директива {$mode objfpc}), я пробовал делать так:
Код: Выделить всё
{$mode objfpc}
...код
{$end mode}

но так не получается. А вообще надо переходить на синтаксис Free Pascal.
AnarchyMob
новенький
 
Сообщения: 13
Зарегистрирован: 16.11.2008 23:44:36

Re: Перевод кода

Сообщение Sergei I. Gorelkin » 10.12.2008 00:57:25

В FPC указатель на любой тип одновременно является указателем на массив элементов этого типа, а в Дельфи это справедливо только для PChar и PWideChar. Поэтому пришлось бы городить что-то наподобие

Код: Выделить всё
type
  bytearray = array[0..3] of byte;
  pPixel = ^bytearray;
...
  pPixel^[0] := rgb;  // "<" в обязательном порядке


Что касается режима компиляции, то он задается только для всего модуля целиком, так что единственный вариант - выносить куски в другой модуль.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Перевод кода

Сообщение AnarchyMob » 10.12.2008 04:14:35

Огромное вам спасибо, вы мне очень помогли. У меня к вам еще вопрос, я так понял в синтаксисе Free Pascal существует жесткая проверка типов, например при регистрации класса нового окна оконную функцию с "дельфовским" синтаксисом я записывал так:
Код: Выделить всё
MyWndClass.WndProc := @MyWndProc;

а с синтаксисом Free Pascal мне уже нужно записывать так:
Код: Выделить всё
MyWndClass.WndProc := WNDPROC(@MyWndProc)

можно ли проверку типов как-то смягчить, может директива какая-нибудь есть, а в целом оставить синтаксис Free Pascal?
AnarchyMob
новенький
 
Сообщения: 13
Зарегистрирован: 16.11.2008 23:44:36

Re: Перевод кода

Сообщение Vadim » 10.12.2008 07:07:29

AnarchyMob
"MyWndClass.WndProc := @MyWndProc;" - эта примочка чисто дельфовая. Если Вам сложно перестроиться, то сначала просто компилируйте в режиме Дельфи и параллельно переписывайте на режим objfpc, только в другом модуле. Это чтобы сравнивать последствия работы там и там.
Дело в том, что "@" даёт нам адрес вообще, в принципе чего угодно, а ведь в конструкцию "MyWndClass.WndProc" нужен вполне определённый тип, согласитесь. Логично в таком случае именно к этому типу и приводить.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Перевод кода

Сообщение AnarchyMob » 10.12.2008 15:06:05

Всё, буду переходить на синтаксис Free Pascal. Он чем то похож на C++.
AnarchyMob
новенький
 
Сообщения: 13
Зарегистрирован: 16.11.2008 23:44:36

Re: Перевод кода

Сообщение shade » 10.12.2008 21:04:36

AnarchyMob писал(а):Я пробовал реализовывать эту функцию с использованием SetPixel & GetPixel, но изображение в таком случае обрабатывается очень долго.

Специально для попиксельной обработки изображений я как-то писал модуль FastBitmap, но для Делфей, под лазарус так и портировал... под Lazarus+win32 адаптировать я думаю будет не сложно...
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11

Рейтинг@Mail.ru