Rozjaśnianie oraz negatyw 8-bitowego szarego obrazka .bmp.

Rozjaśnianie oraz negatyw 8-bitowego szarego obrazka .bmp.
Al0n3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
0

Witam, chciałbym prosić o pomoc w napisaniu programu w C++ za pomocą struktur, który będzie zamieniał na negatyw albo rozjaśniał obraz. Tak jak w temacie, obrazek jest z góry określony 320 x 200, 8-bitowy, szary.

Przykład :
boat.bmp

W internecie występuje masa takich programów, lecz są pisane nie według mojego wzoru, co bardzo utrudnia zrozumienie kodu. Moi wykładowcy nie tłumaczą nic, a wymagają.

Muszę się stosować do wzoru niżej przedstawionego (chodzi mi o struktury i wywołanie pliku, resztę dopisałem sam).

Kopiuj
#include <stdio.h>
#include <dos.h> 
#include <iostream>

/* File Header */
struct BMPFILEHEADER {
        short type;
        int fileSize;
        short reserved0;
        short reserved1;
        int dataOffset;
};
 
/* Info Header */
struct BMPINFOHEADER {
        int hdrSize;
        int width;
        int height;
        short planes;
        short depth;
        int compression;
        int bmpDataSize;
        int hResolution;
        int vResolution;
        int nColors;
        int nImportantColors;
};

struct RGB {
      unsigned char R;
      unsigned char G;
      unsigned char B;
      unsigned char rgbReserved;
     };

int main(int argc, char *argv[], char *envp[])
{
	int wybor=1;
	
	FILE *bitmap_file; //Plik bitmapy
	BMPFILEHEADER FileInfo; //nagłówek nr 1 bitmapy
	BMPINFOHEADER PictureInfo; //nagłówek nr 2 bitmapy
	//otwórz plik do odczytu w trybie binarnym "rb"
	bitmap_file = fopen("c:\\Programy\\boat.bmp", "rb");
	//odczytaj z pliku nagłówek nr 1 i zapamiętaj w zmiennej bmfh
	fread(&bmfh, sizeof(BMPFILEHEADER), 1, bitmap_file);
	//odczytaj z pliku nagłówek nr 2 i zapamiętaj w zmiennej bmih
	fread(&bmih, sizeof(BMPINFOHEADER), 1, bitmap_file);
	//zamknij plik
	fclose(bitmap_file);
	
	while(wybor==1 || wybor==2)
	{
		cout<<"Co chcesz zrobić ?"<<endl
			<<"1. Rozjasnienie."<<endl
			<<"2. Negatyw."<<endl
			<<"3. Koniec programu.";
		
			cin>>wybor; 
			
		switch(wybor)
		{
			case 1:
			
					break;
			case 2:
					break;
				
			case 3:	system("pause");
					return 0;
		}
		system("cls");
	}
    system("pause");
return 0;   
}

Program miałby pokazywać otrzymany obraz za pomocą trybu 13h. Jako pomoc miałem podane dane kody:

Kopiuj
 #include <dos.h>
 ...
 REGPACK regs;
 regs.r_ax = 0x13;
 intr(0x10, &regs); 
Kopiuj
 unsigned char *video_memory = (BYTE *)0xA0000000L;
 //ustaw lewy górny piksel obrazu na kolor 128
 //aktualnej palety karty VGA
 video_memory[0] = 128;
 //ustaw prawy dolny piksel obrazu na kolor 255
 //aktualnej palety karty VGA
 video_memory[64000] = 255; 
Kopiuj
outportb(0x03C8, 0); //rozpocznij ustawianie palety od koloru nr 0
for (int i = 0; i < 255; i++) //ilość kolorów w palecie 8-bitowej
{
 outp(0x03C9, palette[i].rgbRed * 63 / 255); //skalowana składowa R
 outp(0x03C9, palette[i].rgbGreen * 63 / 255); //skalowana składowa
 outp(0x03C9, palette[i].rgbBlue * 63 / 255); //skalowana składowa B
}  

Niestety, brak pomocy wykładowców przyczynia się do braku zrozumienia danego kodu i sposobu jego wykorzystania. By był ktoś tak miły by wytłumaczyć mi oraz pomóc zrobić dany program?

pasasap
  • Rejestracja: dni
  • Ostatnio: dni
1
Kopiuj
while(wybor==1 && wybor==2)

Gdzie studiujesz?

Kopiuj
cout<"Co chcesz zrobić ?"<endl <<"1.="&lt;&lt;&quot;1." <<"2.="&lt;&lt;&quot;2." <<"3.="&lt;&lt;&quot;3." programu.";="programu.&quot;;" cin="cin" rozjasnienie."<<endl="Rozjasnienie.&quot;&lt;&lt;endl" negatyw."<<endl="Negatyw.&quot;&lt;&lt;endl" koniec="Koniec">>wybor;  

Tutaj to zakręciłeś dopiero ;')

I znalazłem coś takiego: https://www.daniweb.com/software-development/c/threads/119232/about-outp-function-in-conio-h-for-c-or-c- Nie ma funkcji outp dla XP, możliwe, że podobnie sytuacja wygląda z win7. Z resztą, ta funkcja jest uznana za przestarzałą, co można zobaczyć tutaj: https://msdn.microsoft.com/en-us/library/ms235415.aspx

Tutaj: http://stackoverflow.com/questions/7317871/problem-in-referencing-the-outportb-function-in-c jest ciekawa linijka: outportb is a DOS anachronism - even if you could get this to compile it wouldn't work under anything newer than Windows 98. – Paul R

Jeśli masz używać tych funkcji, to powodzenia ;')

Al0n3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
0

Studiuje na politechnice Łódzkiej. Akurat to co zacytowałeś zapomniałem zmienić "and" na "or" oraz nie zauważyłem (głupi błąd), że napisy pozmieniało mi na inne znaki. Poprawione.

Ogólnie przedmiot to architektura komputerów. Normalnie pisaliśmy programy w Assemblerze i kompilowaliśmy w DosBoxie. Fajnie to wyglądało dali dam zadanie, bibliotekę assemblera i proszę zrobić. Zawsze mieliśmy programy z rocznika wcześniej żeby się wzorować, tym razem niestety rok temu pisano ten program w assemlerze, a nie jak w tym roku w c++.

Program mamy skompilować za pomocą bcc w DosBoxie.

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

Jeśli masz używać tych funkcji, to powodzenia ;')

Nie ma się co czepiać "anachronizmów", bo skoro jest narzucony BCC i DOSBox to jest narzucony.

By był ktoś tak miły by wytłumaczyć mi oraz pomóc zrobić dany program?

Większość potrzebnych kawałków już masz. Reszta wymaga tylko myślenia.
Zacznij od wyświetlania nieprzerobionego obrazka. Masz zdefiniowaną tablicę video_memory. Wskazuje bezpośrednio na pamięć ekranu - co tam wpiszesz, wyświetli się na ekranie.
Trzeba pod ten wskaźnik skopiować wczytaną bitmapę.

Format BMP masz wyjaśniony na Wikipedii. Zwłaszcza diagram po prawej powinien wyjaśnić, gdzie są dane. Ładowanie nagłówka już masz.

Al0n3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
0

Trochę nad tym siedziałem, coś udało się wykombinować.

Kopiuj
#include <iostream.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <conio.h>


struct BITMAPFILEHEADER
{
 short bfType;                    //Opis formatu pliku. Musi być ‘BM’.
 int bfSize;                   //Rozmiar pliku BMP w bajtach.
 short bfReserved1;               //Zarezerwowane. Musi być równe 0
 short bfReserved2;               //Zarezerwowane. Musi być równe 0.
 int bfOffBits;                //Przesunięcie w bajtach początku danych
 };                                             //obrazu liczone od końca struktury

 struct RGBQUAD
 {
 unsigned char rgbBlue;
 unsigned char rgbGreen;
 unsigned char rgbRed;
 unsigned char rgbReserved;
 };



struct BITMAPINFOHEADER
 {
 int biSize;                   //Rozmiar struktury BITMAPINFOHEADER.
 int biWidth;                  //Szerokość bitmapy w pikselach.
 int biHeight;                 //Wysokość bitmapy w pikselach.
 short biPlanes;                  //Ilość płaszczyzn. Musi być 1.
 short biBitCount;                //Głębia kolorów w bitach na piksel.
 int biCompression;            //Rodzaj kompresji (0 – brak).
 int biSizeImage;              //Rozmiar obrazu w bajtach. Uwaga może być 0.
 int biXPelsPerMeter;          //Rozdzielczość pozioma w pikselach na metr.
 int biYPelsPerMeter;          //Rozdzielczość pionowa w pikselach na metr.
 int biClrUsed;                //Ilość używanych kolorów z palety.
 int biClrImportant;           //Ilość kolorów z palety niezbędnych do
 };                                             //wyświetlenia obrazu.


int main()
{

FILE *bitmap_file;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD palette;
char m;
char wyjscie[5];
int i,j;

bitmap_file = fopen("lena.bmp", "rb");
    fread(&bmfh, sizeof(BITMAPFILEHEADER), 1, bitmap_file);
    //odczytaj z pliku nagłówek nr 2 i zapamiętaj w zmiennej bmih
    fread(&bmih, sizeof(BITMAPINFOHEADER), 1, bitmap_file);
    //zamknij plik
    fclose(bitmap_file);
    
cout<<"Podaj co chcesz zrobic: n-negatyw, r-rozjasnianie, p-przyciemanianie"<<endl;
cin>>m;

 REGPACK regs;
 regs.r_ax = 0x13;
 intr(0x10, &regs);

switch (m)
{
    case 'n':
    case 'N':

    unsigned char *video_memory = (BYTE *)0xA0000000L;
for(i=0; i<320; i++)
{
    for(j=0; j<200; j++)
    {
        video_memory[i*j] = ~video_memory[i*j];
    }
}
    break;

 /*   case 'r':
    case 'R':

    for (i = 0; i < 255; i++)
{
    if(palette[i].rgbRed+'25'<='255' && palette[i].rgbRed+'25'>='0')
    {
        palette[i].rgbRed+=25;
    }
    if(palette[i].rgbGreen+25<=255 && palette[i].rgbGreen+25>=0)
    {
        palette[i].rgbGreen+=25;
    }
    if(palette[i].rgbBlue+25<=255 && palette[i].rgbBlue+25>=0)
    {
        palette[i].rgbBlue+=25;
    }
}
    break;
 */   
    /*case 'p':
    case 'P':

    for (i = 0; i < 255; i++)
{
    if(palette[i].rgbRed-25<=255 && palette[i].rgbRed-25>=0)
    {
        palette[i].rgbRed=palette[i].rgbRed+25;
    }
    if(palette[i].rgbGreen-25<=255 && palette[i].rgbGreen-25>=0)
    {
        palette[i].rgbGreen=palette[i].rgbGreen+25;
    }
    if(palette[i].rgbBlue-25<=255 && palette[i].rgbBlue-25>=0)
    {
        palette[i].rgbBlue=palette[i].rgbBlue-25;
    }
}
    break;*/
}
    return 0;
}

Ogólnie jak zakomentuje te dwie opcje (dają mi błędy, że nie może skonwertować tej struktury na int) to mam błąd dotyczący 'BYTE'. Nie wiem w sumie jak go naprawić bo miałem tak narzucone z góry. Jakieś pomysły ?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.