#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #define MAXSTRLEN 100 int odczyt_pliku(struct obraz* hp1); int zapis_pliku(struct obraz hp1); void zapis_histogram(int* ile, struct obraz hp1); void zwalnianie_pamieci(struct obraz* hp1); void zwalnianie_blad(struct obraz* hp1, int ile); int obrot(struct obraz* hp1); void histogram(struct obraz* hp1); void negatyw(struct obraz* hp1); void pieprz_sol(struct obraz* hp1); int filtr(struct obraz* hp1); void progowanie(struct obraz* hp1); struct obraz kopia_zapasowa(struct obraz* hp1); struct obraz { char* nazwa_pliku; char* standard; int szerokosc; int wysokosc; int zakres; int** piksele; //tablica na piksele }; int main() { char nazwa[MAXSTRLEN]; int x; int k = 0; //int* ile; int wybor = 1;//menu 1 int krok_programu = 0;//menu 2 struct obraz* hp1;//deklaracja zmiennej strukturalnej struct obraz kopia_robocza; hp1 = (struct obraz*)malloc(1 * sizeof(struct obraz));//alokacja pamieci srand(time(NULL)); do { switch (wybor) { case 1: x = odczyt_pliku(hp1);// odczyt z pliku if (x == 0) break; if (x == 1) { kopia_robocza = kopia_zapasowa(hp1);//kopia robocza danego pliku do { puts("Mozliwe operacje na odczytanym obrazie:"); puts("wpisz 'obrot' aby obrocic obraz"); puts("wpisz 'histogram' aby stworzyc histogram dla wczytanego obrazu"); puts("wpisz 'neg' aby uzyc negatywa"); puts("wpisz 'szum' aby uzyc efektu pieprz i sol"); puts("wpisz 'filtr' aby uzyc filtru na obraz"); puts("wpisz 'save' aby zapisac obraz"); puts("wpisz 'exit' aby wyjsc z programu"); while (!scanf("%s", nazwa)) { char c; while (c = getchar() != '\n'); } if (!strcmp(nazwa, "obrot")) { krok_programu = 1; } else if (!strcmp(nazwa, "histogram")) { krok_programu = 2; } else if (!strcmp(nazwa, "neg")) { krok_programu = 3; } else if (!strcmp(nazwa, "szum")) { krok_programu = 4; } else if (!strcmp(nazwa, "filtr")) { krok_programu = 5; } else if (!strcmp(nazwa, "save")) { krok_programu = 6; } else if (!strcmp(nazwa, "exit")) { krok_programu = 7; } switch (krok_programu) { case 1: puts("Podaj wielokrotnosc kata 90 stopni:"); k = getch(); for (int i = 0; i < k - 48; i++) { obrot(&kopia_robocza);//przekazanie kopii } puts("Wykonano obrot"); Sleep(1000); break; case 2: histogram(&kopia_robocza); puts("histogram zostal utworzony"); Sleep(10000); break; case 3: negatyw(&kopia_robocza); puts("wykonano negatyw"); Sleep(3000); break; case 4: pieprz_sol(&kopia_robocza); puts("Przyprawy"); Sleep(1000); break; case 5: filtr(&kopia_robocza); puts("przefiltrowano"); Sleep(1000); break; case 6: zapis_pliku(kopia_robocza);//zapis musi byc oddzielna funkcja, dodac petle do zwalnianie_pamieci(hp1); break; case 0: puts("Podano nieprawidlowa wartosc"); Sleep(1000); break; default: wybor = 2; break; } system("cls"); } while (krok_programu != 7); } else { printf("Problem z alokacja %d wiersza, zwalniam pamiec\n", x); zwalnianie_blad(hp1, x); exit(0); } break; case 2: exit(0); break; default: break; } } while (wybor != '2'); return 0; } int odczyt_pliku(struct obraz* hp1) { FILE* plik; char komentarze; hp1->nazwa_pliku = (char*)malloc(100 * sizeof(char));//alokacja tablicy z nazwa printf("Podaj nazwe pliku:\n"); scanf("%s", hp1->nazwa_pliku);//wczytanie nazwy obrazu plik = fopen(hp1->nazwa_pliku, "r");//otwarcie pliku o podanej nazwie if (plik == NULL)//czy plik sie otworzyl { puts("Plik nie zostal odnaleziony");//komunikat dlaczego blad return 0; } else puts("Znaleziono plik"); //czytanie standardu //Jezeli napotka # to usuwa wszystko co jest dalej po nim (wrzuca do zmiennej komentarz ktora przyjmuje kolejno wartosci pobrane) az do nowej lini a jezeli nie bedzie to # to sie cofnie o 1 i zapisze to wszystko do standardu fscanf(plik, "%c", &komentarze); //czytanie pojedynczego znaku while (komentarze == '#')//szukanie komentarzy { while (komentarze != '\n')//dopoki nie jest nowa linia (spacja) { fscanf(plik, "%c", &komentarze); } fscanf(plik, "%c", &komentarze);//przeskok do nowej lini } fseek(plik, -1, SEEK_CUR); //przesuniecie znacznika pliku o jeden w tył fscanf(plik, "%s\n", &hp1->standard);//musi być na adres :)(hp1->wysokosc) * sizeof&(hp1->piksele) //czytanie do nowej linii //czytanie szerokosci //taka sama zasada fscanf(plik, "%c", &komentarze); while (komentarze == '#') { while (komentarze != '\n') { fscanf(plik, "%c", &komentarze); } fscanf(plik, "%c", &komentarze); } fseek(plik, -1, SEEK_CUR); fscanf(plik, "%d", &hp1->szerokosc); //czytanie wysokosci fscanf(plik, "%c", &komentarze); while (komentarze == '#') { while (komentarze != '\n') { fscanf(plik, "%c", &komentarze); } fscanf(plik, "%c", &komentarze); } fseek(plik, -1, SEEK_CUR); fscanf(plik, "%d", &hp1->wysokosc); //czytanie maksWartosciSzarosci fscanf(plik, "%c", &komentarze); while (komentarze == '#') { while (komentarze != '\n') { fscanf(plik, "%c", &komentarze); } fscanf(plik, "%c", &komentarze); } fseek(plik, -1, SEEK_CUR); fscanf(plik, "%d", &hp1->zakres); //DEKLARACJA pamieci na tablice 2 wymiary hp1->piksele = (int**)malloc(hp1->wysokosc * sizeof(int)); //tworzenie tablicy dynamicznej w pionie if (hp1->piksele != NULL) { for (int i = 0; i < (hp1->wysokosc); i++) { hp1->piksele[i] = (int*)malloc(hp1->szerokosc * sizeof(int)); //tworzenie tablic dynamicznych w poziomie - w kazdym elemencie tablicy z pionu powstaje tablica w poziomie tworzac macierz if (hp1->piksele[i] == NULL) { return i; } } //Odczytanie wartosci pikseli z pliku i przepisanie ich do utworzonej tablicy dynamicznej for (int i = 0; i < hp1->wysokosc; i++) { for (int j = 0; j < hp1->szerokosc; j++) { fscanf(plik, "%c", &komentarze);//czyta znak while (komentarze == '#')//jezeli komentarz { while (komentarze != '\n')//dopóki nie \n { fscanf(plik, "%c", &komentarze); } fscanf(plik, "%c", &komentarze); } fseek(plik, -1, SEEK_CUR); //jezeli nie komentarz to cofa sie o 1 fscanf(plik, "%d", &hp1->piksele[i][j]); //i pobiera go do macierzy } } printf("standard:%s\n", &hp1->standard); } else { puts("problem z alokacja tablicy"); fclose(plik); return 0; } fclose(plik); return 1; } int zapis_pliku(struct obraz hp1) { FILE* plik; char x = 0; hp1.nazwa_pliku = (char*)malloc(100 * sizeof(char));//alokacja tablicy z nazwa puts("Podaj nazwe pliku:"); scanf("%s", hp1.nazwa_pliku);//wczytanie nazyw obrazu plik = fopen(hp1.nazwa_pliku, "w");//otwarcie pliku o podanej nazwie if (plik == NULL)//czy plik sie utworzyl { perror("Tablice.csv");//komunikat dlaczego blad return 0; } fprintf(plik, "%s\n", &hp1.standard); fprintf(plik, "%d %d\n", hp1.szerokosc, hp1.wysokosc); fprintf(plik, "%d\n", hp1.zakres); for (int i = 0; i < hp1.wysokosc; i++)//wpisanie wartosci z pliku { for (int j = 0; j < hp1.szerokosc; j++) { fprintf(plik, "%d ", hp1.piksele[i][j]); } fprintf(plik, "\n"); } fclose(plik); puts("Utworzono plik"); Sleep(1000); return 1; } void zwalnianie_pamieci(struct obraz* hp1) { for (int i = 0; i < (hp1->wysokosc); i++) { free((hp1->piksele[i])); } free((hp1->piksele)); } void zwalnianie_blad(struct obraz* hp1, int ile) { for (int i = 0; i < ile; i++) { free((hp1->piksele[i])); } free((hp1->piksele)); } struct obraz kopia_zapasowa(struct obraz* hp1)//kopia robocza aby mozna ten sam obraz przekształcać { int i, j; struct obraz kopia_robocza; kopia_robocza.zakres = hp1->zakres;//przepisanie wartosci kopia_robocza.szerokosc = hp1->szerokosc; kopia_robocza.wysokosc = hp1->wysokosc; kopia_robocza.standard = hp1->standard; kopia_robocza.nazwa_pliku = hp1->nazwa_pliku; kopia_robocza.piksele = (int**)malloc(hp1->wysokosc * sizeof(int));//alokacja pamieci if (kopia_robocza.piksele != NULL) { for (i = 0; i < hp1->wysokosc; i++) { kopia_robocza.piksele[i] = (int*)malloc(hp1->szerokosc * sizeof(int)); if (kopia_robocza.piksele == NULL) { printf("BLAD!!!"); zwalnianie_blad(&kopia_robocza, i); } } } else printf("BLAD!!!"); for (i = 0; i < hp1->wysokosc; i++) { for (j = 0; j < hp1->szerokosc; j++) { kopia_robocza.piksele[i][j] = hp1->piksele[i][j]; } } return kopia_robocza; } int obrot(struct obraz* hp1) { int i, j; struct obraz kopia_robocza; kopia_robocza = kopia_zapasowa(hp1);//utworzenie lokalnej kopi for (i = 0; i < hp1->wysokosc; i++)//pamieci sie sypala dlatego czyszczenie { free(hp1->piksele[i]); } free(hp1->piksele); hp1->szerokosc = kopia_robocza.wysokosc;//przepisanie wartosci hp1->wysokosc = kopia_robocza.szerokosc; hp1->piksele = (int**)malloc(hp1->wysokosc * sizeof(int));//alokacja if (hp1->piksele != NULL) { for (i = 0; i < hp1->wysokosc; i++) { hp1->piksele[i] = (int*)malloc(hp1->szerokosc * sizeof(int)); if (hp1->piksele == NULL) return 1; } } for (i = 0; i < hp1->wysokosc; i++) { for (j = 0; j < hp1->szerokosc; j++) { hp1->piksele[i][j] = kopia_robocza.piksele[j][kopia_robocza.szerokosc - i - 1];//obrot } } for (i = 0; i < kopia_robocza.wysokosc; i++) { free(kopia_robocza.piksele[i]);//zwalnianie lokalnej } free(kopia_robocza.piksele); return 0; } void histogram(struct obraz* hp1)//to dziala, problem z zapisem { int i, j, z; int licznik = 0; int max = 0; int* tab; //deklaracja tablicy na zapisywanie wynikow do histogramu tab = (int**)malloc(hp1->zakres * sizeof(int)); for (z = 0; z < hp1->zakres + 1; z++) //+1 bo nie lapalo maksymalnej wartosci piksela { for (i = 0; i < hp1->wysokosc; i++) { for (j = 0; j < hp1->szerokosc; j++) { if (hp1->piksele[i][j] == z) { licznik++; } } } printf("pikseli o wartosci [%d] jest %d\n", z, licznik); tab[z] = licznik; licznik = 0; } //zapis do pliku csv FILE* plik; z = 0; plik = fopen("histogram.csv", "w"); if (plik == NULL)//czy plik sie otworzyl { perror("histogram.csv");//komunikat dlaczego blad } for (z = 0; z < hp1->zakres + 1; z++) { fprintf(plik, "%d; %d\n", z, tab[z]); } fclose(plik); printf("histogram zostal zapisany do pliku csv\n"); } void negatyw(struct obraz* hp1) { int i, j; for (i = 0; i < hp1->wysokosc; i++) { for (j = 0; j < hp1->szerokosc; j++) { hp1->piksele[i][j] = hp1->zakres - hp1->piksele[i][j];//wzor z instrukcji } } } void pieprz_sol(struct obraz* hp1) { int i, j; for (i = 0; i < hp1->wysokosc; i++) { for (j = 0; j < hp1->szerokosc; j++) { if (rand() % 11 < 1)//prawdopodobienstwo { if (rand() % 2) hp1->piksele[i][j] = 0; else { hp1->piksele[i][j] = hp1->zakres; } } } } } int filtr(struct obraz* hp1) { int gauss[3][3] = { {1,2,1}, {2,4,2}, {1,2,1} }; int i, j, k, l; int okno = 0; int suma = 16; struct obraz kopia_robocza; kopia_robocza = kopia_zapasowa(hp1); for (i = 0; i < hp1->wysokosc - 2; i++) { for (j = 0; j < hp1->szerokosc - 2; j++) { for (k = 0; k < 3; k++) { for (l = 0; l < 3; l++) { okno = okno + kopia_robocza.piksele[i + k][j + l] * gauss[k][l]; } } hp1->piksele[i + 1][j + 1] = okno / suma; okno = 0; } } for (i = 0; i < kopia_robocza.wysokosc; i++) { free(kopia_robocza.piksele[i]); } free(kopia_robocza.piksele); return 0; }