Strona 1 z 1

GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 06:49
przez Corvis
Witam,

Napisałem sobie funkcję do zamiany kolorów na klasie TBitmap:

Kod który to realizuje:

Kod: Zaznacz cały
bmpOrginal->LoadFromFile(NazwaPliku);
        TRGBTriple *ptr = 0;
        for(int i=0;i < bmpOrginal->Height;i++) {
            ptr = reinterpret_cast<TRGBTriple *>(bmpOrginal->ScanLine[i]);

            for(int j=0; j < bmpOrginal->Width; j++) { 
                if(ptr[j].rgbtRed == 0xFF && ptr[j].rgbtGreen == 0xFF && ptr[j].rgbtBlue == 0xFF) {
                    ptr[j].rgbtBlue   = 0xC0;
                    ptr[j].rgbtGreen  = 0xC0;
                    ptr[j].rgbtRed    = 0xC0;
                } else {
                    ptr[j].rgbtBlue   = 0x00;
                    ptr[j].rgbtGreen  = 0x00;
                    ptr[j].rgbtRed    = 0x00;
                }
            }
        }


Teraz chce zrobić coś podobnego na klasie Gdiplus::bitmap, posiada ona metody GetPixel() i SetPixel() i robiąc to w ten sposób:
Kod: Zaznacz cały
for(int i=0;i<bitmapa->GetWidth(); ++i) {
    for(int j=0;j<bitmapa->GetHeight(); ++j) {
      // tutaj pobranie koloru za pomocą GetPixel i zamiana go za pomocą SetPixel;
     }
}


Chodzi to piekielnie wolno bo robi to po pixelu. Czy da się to zrobić za pomocą GDI szybciej ??

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 07:43
przez Corvis
Problem rozwiązany podaje kod:


Kod: Zaznacz cały
    Gdiplus::Graphics NowyObrazek(Image1->Canvas->Handle);
   
    NowyObrazek.Clear(clBlack);
    NowyObrazek.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); // sposób skalowania obrazka

    Gdiplus::ColorMap cm[3]; // mapa zmiany kolorów

    cm[0].oldColor = Gdiplus::Color(0xFF,0xFF,0xFF); 
    cm[0].newColor = Gdiplus::Color(0xC0,0xC0,0xC0);

    cm[1].oldColor = Gdiplus::Color(0xFF,0x00,0xFF);
    cm[1].newColor = Gdiplus::Color(0x00,0x00,0x00);

    cm[2].oldColor = Gdiplus::Color(0x00,0x00,0xFF);
    cm[2].newColor = Gdiplus::Color(0x00,0x00,0x00);

    Gdiplus::ImageAttributes imgAttrs;
    imgAttrs.SetRemapTable(3,cm,Gdiplus::ColorAdjustTypeBitmap);

    NowyObrazek.DrawImage(
        bmp,
        Gdiplus::Rect(0, 0, MalowanieW, MalowanieH),  // MalowanieW , MalowanieH ( Dlugosc i szerokosc obrazka jaka chcemy uzyskac )
        0,
        0,
        bmp->GetWidth(),
        bmp->GetHeight(),
        Gdiplus::UnitPixel,
        &imgAttrs
    );



Mam też inne pytanie:

Czy za każdym razem trzeba pobierać uchwyt :
Kod: Zaznacz cały
Gdiplus::Graphics NowyObrazek(Image1->Canvas->Handle);

i ustawiać tą zamianę kolorów, podczas przemalowywania ??

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 09:41
przez polymorphism
Czy za każdym razem trzeba pobierać uchwyt :

A w czym problem?

(...) i ustawiać tą zamianę kolorów, podczas przemalowywania ??

No raczej. DrawImage służy do malowania bitmapy, a nie zmiany trybu pracy obiektu klasy Graphics. Jeśli tego typu ustawienia miałyby mieć charakter globalny (w ramach obiektu), zrobiliby oddzielną, specjalnie do tego celu metodę.

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 10:42
przez Cyfrowy Baron
Czy za każdym razem trzeba pobierać uchwyt :


Tego inaczej nie da się chyba zrobić.

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 11:49
przez Corvis
A w czym problem?


Może to nie problem ale moje bmp są duże:

2643x1775 i zajmują po 10 mb.

Dlatego pytam bo troche boli komputer mielenie takich bmp :)

Odrazu odpowiadam na kolejne pytanie dlaczego takie duże skaluje - dla uzyskania jak najlepszej jakości obrazu do późniejszego zaznaczania na nim.


Pozdrawiam

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 12:02
przez Cyfrowy Baron
Jak to się ma do pobierania uchwytu?

Kod: Zaznacz cały
Gdiplus::Graphics NowyObrazek(Image1->Canvas->Handle);


Przecież pobranie uchwytu nie generuje jakichś opóźnień, wszak pobierasz uchwyt do Canvas obiektu Image i na nim rysujesz, przechowywanie tego uchwytu w pamięci niczego nie zmieni. Opóźnienie wywołuje funkcja DrawImage, ale tutaj niczego nie przyspieszysz, gdyż na wykonania zadania funkcja potrzebuje czasu i czy byś przechowywał uchwyt do obiektu w pamięci, czy też pobierasz go na bieżąco niczego nie przyspieszysz.

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: piątek, 25 czerwca 2010, 12:05
przez polymorphism
Może to nie problem ale moje bmp są duże: (...)

No ale uchwyt, o którym mowa jest uchwytem kontekstu urządzenia (HDC), zatem kwestia wielkości bitmap nie ma większego związku z nim.

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: poniedziałek, 28 czerwca 2010, 09:57
przez Corvis
Jeszcze jedno pytanie:

Czy ten uchwyt trzeba zwalaniać jakoś ?

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: poniedziałek, 28 czerwca 2010, 10:09
przez polymorphism
Nie, ponieważ właścicielem kontekstu jest obiekt Image1.

Re: GDI PLUS - Szybka zamiana kolorów w obrazku

Nowy postNapisane: poniedziałek, 28 czerwca 2010, 10:12
przez Corvis
dzieki