Witam!
Mam do napisania program, który będzie edytował zdjęcia (m. in. rozjaśnianie, kontrast, negatyw, histogram etc.). Na 24-bitowych plikach BMP szło dość gładko. Kłopot natomiast pojawił się, gdy chciałem to samo zrobić na plikach czarno-białych (BMP 8-bit). Poniżej zamieszczam fragment kodu, który obsługuje mi zmianę kolorowego obrazka na negatyw i prosiłbym o podobne rozwiązanie tylko w odniesieniu do 8-bitowego pliku:
PixelFormat formatObrazka = (obrazekOryginal.PixelFormat == PixelFormat.Format8bppIndexed) ? PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb; //określenie formatu obrazka
obrazek = new Bitmap(obrazek.Width, obrazek.Height, formatObrazka);
BitmapData daneWyjsciowe = obrazek.LockBits(new Rectangle(0, 0, obrazek.Width, obrazek.Height), ImageLockMode.ReadWrite, formatObrazka); //Blokowanie bitmapy w pamięci, pierwsze dwa argumenty to początek i koniec obrazka,
//kolejne to sposób dostępu i format.
BitmapData daneWejsciowe = obrazekOryginal.LockBits(new Rectangle(0, 0, obrazek.Width, obrazek.Height), ImageLockMode.ReadOnly, formatObrazka);
unsafe
{
byte* wskWyjsciowy = (byte*)daneWyjsciowe.Scan0; //wskaźnik na początek danych w pamięci
byte* wskWejsciowy = (byte*)daneWejsciowe.Scan0;
int nOffset = daneWejsciowe.Stride - obrazek.Width;
switch (RT) {
case trans.NEGATYW:
for (int y = 0; y < obrazek.Height; y++)
{
for (int x = 0; x < obrazek.Width; x++)
{
wskWyjsciowy[0] = (byte)(255 - wskWejsciowy[0]);
wskWyjsciowy[1] = (byte)(255 - wskWejsciowy[1]);
wskWyjsciowy[2] = (byte)(255 - wskWejsciowy[2]);
wskWejsciowy += 3; wskWyjsciowy += 3;
}
wskWejsciowy += nOffset; wskWyjsciowy += nOffset;
}
break;
.....
}
Dwa słowa na temat powyższego kodu: wskWejsciowy i wskWyjsciowy to wskaźniki do obrazów, jeden oryginalny, drugi tworzony w programie. nOffset to fragment lini, w której nie ma już wartości pikseli, a są dodatkowe dane (w zasadzie nie wiem jakie, jak ktoś mi powie to będę wdzięczny).
Z początku myślałem, że wystarczy stworzyć nowy obiekt klasy Bitmap (ten, na którym będą nakładane poprawki) w formacie Format8bppIndexed i działać cały czas na wskWyjsciowe[0] (zwiększając w pętli wskWyjsciowy zawsze o jeden, ale to nie działa tak jak powinno, ale być może coś źle zrobiłem, więc jak komuś to działa w ten sposób, to chętnie posłucham kilku dobrych rad.
Od razu chciałem zaznaczyć, że metody getPixel i setPixel zupełnie mnie nie satysfakcjonują, bo strasznie wolno działają.
Za wszelką pomoc z góry dziękuję :)
P.S.: W części kodu zaznaczonego kropkami są inne algorytmy edytujące, zamknięcie trybu unsafe i zwolnienie zablokowanych plików, ale to wszystko działa na 24-bitowych dokumentach bmp, więc nie zamieszczałem tego, żeby niepotrzebnie nie gmatwać kodu