На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Страницы: (3) 1 [2] 3  все  ( Перейти к последнему сообщению )  
> Как сделать черно-белое изображение
    Хм, ну это понятно. Расскажу подробней.
    У меня есть компоненты Image1 и Image2 и есть кнопка, по нажатию которой картинка Image1 должна становиться серой и выводиться в Image2.
    Вставляю код в обработчик кнопки и.... из Image1 исчезает картинка, в Image2 ничего не появляется. Подразумеваю, что что-то все таки не так)
      Ну можно вот так попробывать сделать ч\б. ТОлько по непонятной причине ч\б становится только часть фото.
      ExpandedWrap disabled
          int Lowpass(BYTE Image[][256], int x, int y)
        {
                int Mask[3][3] = {{1, 1, 1,}, {1, 1, 1}, {1, 1, 1}};
                int i, j, sum=0;
         
                for (j=-1; j<=1; j++)
                        for (i=-1; i<=1; i++)
                              sum += Image[x+i][y+j]*Mask[i+1][j+1];
                return INT(sum/9.0);
        }
        void __fastcall TForm1::Button1Click(TObject *Sender)
        {
           BYTE ImageData[256][256], *LinePtr;
                BYTE Output[256][256];
                int x, y;
         
                
                for (y=0; y<=255; y++)
                {
                        LinePtr = (BYTE *) Image1->Picture->Bitmap->ScanLine[y];
                        for (x=0; x<=255; x++)
                                ImageData[x][y] = LinePtr[x];
                }
              
                for (y=1; y<=254; y++)
                        for (x=1; x<=254; x++)
                                Output[x][y] = Lowpass(ImageData, x, y);
                
                for (y=0; y<=255; y++)
                {
                        LinePtr = (BYTE *) Image1->Picture->Bitmap->ScanLine[y];
                        for (x=0; x<=255; x++)
                                LinePtr[x] = Output[x][y];
                }
                Image1->Refresh();
        }
      Сообщение отредактировано: Kamenev_D -
        Спасибо за идею, однако не получается.
        Выскакивает окно

        project project1.exe raised exception class EInvalid Graphic Operation with message "Scan line index out of range". Process stopped....
          Цитата Klaribel @
          Выскакивает окно

          Загрузи фото другого размера. И обязательно bmp
            А если мне именно надо jpg и именно такого размера (160х128)?=)
              ну попробуй сначала загрузить bmp такого размера
                Ну да, bmp и большего размера прога обрабатывает, но действительно только маленькую часть. С jpg, пределанный в bmp и большего, и такого же размера работать отказывается:(
                  Кстати, я так и не понял почему не обрабатывается вся фото. Выдернул кусок кода из проекта просто. Но раньше то работал же.
                  Может кто-то подскажет почему так происходит.
                    Если в Image1 загружен не bmp-формат (jpg, png и т.д.) то можно просто скопировать эту картинку в промежуточный bmp, его "засерить" и заасайнить его уже в Image2.

                    ExpandedWrap disabled
                        // копирование в промежуточный bitmap
                        Graphics::TBitmap* bitmap = new Graphics::TBitmap();
                        bitmap->Width = Image1->Width;
                        bitmap->Height = Image1->Height;
                        BitBlt(bitmap->Canvas->Handle, 0, 0, bitmap->Width, bitmap->Height, Form1->Canvas->Handle, Image1->Left, Image1->Top, SRCCOPY);
                       
                        // "засеривание" промежуточного bitmap'а
                        bitmap->PixelFormat = pf24bit;
                        for (int y = bitmap->Height - 1; y >= 0; --y)
                        {
                          TRGBTriple* scanLine = (TRGBTriple*)bitmap->ScanLine[y];
                          for (int x = bitmap->Width - 1;  x >= 0; --x)
                          {
                            const BYTE gray = 0.222 * scanLine[x].rgbtRed +
                                              0.707 * scanLine[x].rgbtGreen +
                                              0.071 * scanLine[x].rgbtBlue;
                            scanLine[x].rgbtGreen = gray;
                            scanLine[x].rgbtRed = gray;
                            scanLine[x].rgbtBlue = gray;
                          }
                        }
                       
                        // копирование промежуточного bitmap'а в Image2
                        Image2->Picture->Assign(bitmap);
                        delete bitmap;


                    Но если картинка не на форме (а на панели например, к канве которой доступа напрямую нет) или поверх картинки какие-то контролы - то тогда сложнее будет.

                    Добавлено
                    Цитата Kamenev_D @
                    Кстати, я так и не понял почему не обрабатывается вся фото

                    У тебя вообще какой-то код кучерявый.. Какие-то три цикла и почему только до 255(254)?!

                    Добавлено
                    о.. прикольно. Знаю как прорисовать Image в любой девайсконтекст (именно прорисовать а не скопировать уже прорисованный).
                    вместо
                    ExpandedWrap disabled
                      BitBlt(bitmap->Canvas->Handle, 0, 0, bitmap->Width, bitmap->Height, Form1->Canvas->Handle, Image1->Left, Image1->Top, SRCCOPY);

                    надо просто
                    ExpandedWrap disabled
                      Image1->Perform(WM_PAINT, (WPARAM)bitmap->Canvas->Handle, 0);

                    и отпадает проблема парента, и возможных контролов поверх картинки... Image1 вообще невидимым может быть!

                    Добавлено
                    Так-с...
                    После всего вышло что можно и вообще без промежуточного битмапа :D
                    Сразу прорисовать Image1 в Image2 и потом последний "засерить":
                    ExpandedWrap disabled
                        Image2->Picture->Bitmap->PixelFormat = pf24bit;
                        Image2->Picture->Bitmap->Width = Image1->Width;
                        Image2->Picture->Bitmap->Height = Image1->Height;
                        Image1->Perform(WM_PAINT, (WPARAM)Image2->Picture->Bitmap->Canvas->Handle, 0);
                       
                        for (int y = Image2->Picture->Bitmap->Height - 1; y >= 0; --y)
                        {
                          TRGBTriple* scanLine = (TRGBTriple*)Image2->Picture->Bitmap->ScanLine[y];
                          for (int x = Image2->Picture->Bitmap->Width - 1;  x >= 0; --x)
                          {
                            const BYTE gray = 0.222 * scanLine[x].rgbtRed +
                                              0.707 * scanLine[x].rgbtGreen +
                                              0.071 * scanLine[x].rgbtBlue;
                            scanLine[x].rgbtGreen = gray;
                            scanLine[x].rgbtRed = gray;
                            scanLine[x].rgbtBlue = gray;
                          }
                        }


                    Работает :)
                      Всем спасибо, завтра попробую, сегодня уже сил нет=)
                        Спасибо огромное! РАБОТАЕТ! :D
                          подскажите ещё одному начинающему программисту, возможно ли провернуть фильтр сепии?
                          пробовал менять формулу серого на формулу коричневого и сепии, но как-то не очень получалось... подскажите плиз)

                          Добавлено
                          откуда формула серого такая? #define Gray(R, G, B) (R*.257 + G*.504+B*.098+16.) есть формулы других цветов?
                            Цитата donotlies @
                            откуда формула серого такая? #define Gray(R, G, B) (R*.257 + G*.504+B*.098+16.) есть формулы других цветов?
                            Откуда там у тебя +16. - это нам не известно. Это очевидно вычисление яркости точки, отображать ее можно в оттенках хоть серого, хоть красного или зеленого. Каких таких других цветов?
                              Цитата donotlies @
                              откуда формула серого такая? #define Gray(R, G, B) (R*.257 + G*.504+B*.098+16.)

                              А от куда ты ее взял?
                              На Википедии приведены такие весовые коэффициенты: 0,222 0,707 и 0,071
                                donotlies
                                Это история старая. Во времена когда создавалось телевидение...

                                Во общем формула отсюда.
                                http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.601-7-201103-I!!PDF-E.pdf

                                Chow
                                Википедия не достоверный источник. Но такая формула тоже существует.

                                А по поводу того какая из них правильная отвечу просто. Во первых не понятно откуда взялась картинка и формат её хранения и способ вывода. Так что с успехом можно применять любую. Но вроде как стандарт CIE преобладает. Так что надо следовать ихним рекомендациям.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 [2] 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0628 ]   [ 15 queries used ]   [ Generated: 5.07.25, 04:16 GMT ]