Guest User

Untitled

a guest
Jan 10th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.74 KB | None | 0 0
  1. #include <iostream>
  2. #include <limits> // std::numeric_limits<>
  3. using namespace std;
  4.  
  5.  
  6. #ifdef __linux
  7. #include <SDL/SDL.h>
  8. #else
  9. #include <SDL.h>
  10. #endif
  11.  
  12. #if __cplusplus < 201103L
  13. #error "Wymagany C++11!"
  14. #endif // __cplusplus
  15.  
  16.  
  17. SDL_Surface* screen;
  18. const int width = 900, height = 600;
  19. const char* title = "GKiM - Lab 7 - Nazwisko Imie";
  20.  
  21.  
  22. /** Reguly oceniania:
  23. - Za bycie źródłem plagiatu -0,5 punkta. Proszę swoje rozwiązanie zlikwidować z komputera.
  24. - Za plagiat przyznaje za zadanie 0 punktow!!! Dodam, ze mam program antyplagiatowy, zresztą Państwo wiedzą
  25. - Za niewpisanie w pliku z kodem swojego Nazwiska i Imienia powyzej [-0.1 punkta]
  26. - Za wrzucenie mi na pendrive/wyslanie na maila/załadowanie na elfa wiecej niz jednego pliku zrodlowego (*.cpp) [-0.1 punkta]
  27. - Za nienazwanie pliku zrodlowego NazwiskoImie.cpp, gdzie Nazwisko i Imie zastepujemy odpowiednio swoim nazwiskiem i imieniem, prosze nie dawac zadnych podkreslen, spacji i numeru grupy [-0.1 punkta].
  28.  
  29. ***************************************** zajecia 7:
  30. Redukcja ilości barw:
  31. Naszym zadaniem jest zmniejszenie palety dla składowej R, podobnie jak ostatnio, ale tym razem będziemy to robić w oparciu o oryginalny obrazek.
  32. Wszystko ma się odbywać w Funkcja1()
  33. 1. Za wyświetlenie ilości unikalnych odcieni zadanej składowej na standardowe wyjście [0.5 punkta].
  34. 2. Za zredukowanie do 7 najczęstszych odcieni danej składowej i wyświetlenie tych najczęstrzych odcieni na standardowe wyjście. [0.5 punkta].
  35. 3. Za wyświetlenie wynikowego obrazka. [1 punkt].
  36.  
  37. Dodatkowo: Za ladny, czytelny, czysty, KONSEKWENTNY kod implementowanych funkcji, zaimplementowanych w 100% [+0.5 punkta].
  38.  
  39. Algorytm redukcji palety:
  40. 1. Znajdujemy wszystkie możliwe wartości zadanej składowej i zliczamy ile razy występuje dana wartość.
  41. 2. Sortujemy wg częstości występowania.
  42. 3. Dla wszystkich składowych poza zadaną ilością najczęściej występujących znajdujemy, który z najczęściej występujących
  43. jest bliższy i wartość danej składowej zastępujemy najbliższą z najcześciej występujących odcieni.
  44. **/
  45.  
  46.  
  47. constexpr static auto MAX_COLOR_VALUE = std::numeric_limits<decltype(SDL_Color::r)>::max();
  48. constexpr static auto MIN_COLOR_VALUE = std::numeric_limits<decltype(SDL_Color::r)>::min();
  49.  
  50.  
  51. void Funkcja1();
  52.  
  53. int initSdl();
  54.  
  55. void loadBMP(const char* nazwa, int x, int y);
  56.  
  57. void clearScreen(Uint8 R=0, Uint8 G=0, Uint8 B=0);
  58.  
  59.  
  60. int main(int argc, char** argv)
  61. {
  62. if (initSdl() )
  63. {
  64. return -1;
  65. }
  66.  
  67. pair<int, int> mousePosition{0, 0};
  68.  
  69. bool done = false;
  70. while (!done)
  71. {
  72. // message processing loop
  73. SDL_Event event;
  74. while (SDL_PollEvent(&event))
  75. {
  76. if (SDL_QUIT == event.type)
  77. {
  78. done = true;
  79. }
  80. else if(SDL_KEYDOWN == event.type)
  81. {
  82. switch(event.key.keysym.sym)
  83. {
  84. case SDLK_ESCAPE:
  85. done = true;
  86. break;
  87. case SDLK_a:
  88. loadBMP("obrazek1.bmp", 0, 0);
  89. break;
  90. case SDLK_s:
  91. loadBMP("obrazek2.bmp", 0, 0);
  92. break;
  93. case SDLK_d:
  94. loadBMP("obrazek3.bmp", 0, 0);
  95. break;
  96. case SDLK_f: // zrodlo ponizszych obrazkow: https://pl.wikipedia.org/wiki/Algorytm_Floyda-Steinberga
  97. loadBMP("obrazek4.bmp", 0, 0);
  98. break;
  99. case SDLK_g:
  100. loadBMP("obrazek5.bmp", 0, 0);
  101. break;
  102.  
  103. case SDLK_b:
  104. clearScreen(0, 0, 0);
  105. break;
  106.  
  107. case SDLK_1:
  108. Funkcja1();
  109. break;
  110. }
  111. }
  112. if(event.type == SDL_MOUSEMOTION)
  113. {
  114. mousePosition = make_pair(event.motion.x, event.motion.y);
  115. }
  116. if(event.type == SDL_MOUSEBUTTONDOWN)
  117. {
  118. cout << "Pressed: (" << mousePosition.first << ", " << mousePosition.second << ")\n";
  119. }
  120. } // end of message processing
  121. } // end main loop
  122. return 0;
  123. }
  124.  
  125. #ifdef _WIN32
  126. // to solve problem: https://stackoverflow.com/questions/5259714/undefined-reference-to-winmain16
  127. int WinMain()
  128. {
  129. return main(1, NULL);
  130. }
  131. #endif // _WIN32
  132.  
  133. int initSdl()
  134. {
  135. if (SDL_Init( SDL_INIT_VIDEO ) < 0)
  136. {
  137. fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
  138. return 1;
  139. }
  140.  
  141. atexit(SDL_Quit);
  142.  
  143. const int bitDepth = 32;
  144.  
  145. /// create a new window
  146. screen = SDL_SetVideoMode(width, height, bitDepth, SDL_HWSURFACE | SDL_DOUBLEBUF);
  147. if ( !screen )
  148. {
  149. printf("Unable to set video: %s\n", SDL_GetError());
  150. return 1;
  151. }
  152.  
  153. SDL_WM_SetCaption(title, NULL);
  154.  
  155. return 0;
  156. }
  157.  
  158. void loadBMP(char const* nazwa, int x, int y)
  159. {
  160. SDL_Surface* bmp = SDL_LoadBMP(nazwa);
  161. if (!bmp)
  162. {
  163. printf("Unable to load bitmap: %s\n", SDL_GetError());
  164. }
  165. else
  166. {
  167. SDL_Rect dstrect;
  168. dstrect.x = x;
  169. dstrect.y = y;
  170. SDL_BlitSurface(bmp, 0, screen, &dstrect);
  171. SDL_Flip(screen);
  172. SDL_FreeSurface(bmp);
  173. }
  174. }
  175.  
  176. void clearScreen(Uint8 R, Uint8 G, Uint8 B)
  177. {
  178. SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, R, G, B));
  179. SDL_Flip(screen);
  180. }
  181.  
  182. inline bool inScreen(int x, int y)
  183. {
  184. return x >= 0 && x < screen->w && y >= 0 && y < screen->h;
  185. }
  186.  
  187. Uint8* getPixelAddress(int x, int y)
  188. {
  189. if (inScreen(x, y))
  190. {
  191. /* Pobieramy informacji ile bajtów zajmuje jeden pixel */
  192. const int bpp = screen->format->BytesPerPixel;
  193.  
  194. /* Obliczamy adres pixela */
  195. return (Uint8*)screen->pixels + y * screen->pitch + x * bpp;
  196. }
  197. return NULL;
  198. }
  199.  
  200. SDL_Color getPixel(int x, int y)
  201. {
  202. Uint8* pixelAddress = getPixelAddress(x, y);
  203.  
  204. SDL_Color color = {};
  205. if (pixelAddress)
  206. {
  207. Uint32 col = 0;
  208.  
  209. memcpy(&col, pixelAddress, screen->format->BytesPerPixel);
  210. SDL_GetRGB(col, screen->format, &color.r, &color.g, &color.b);
  211. }
  212.  
  213. return color;
  214. }
  215.  
  216. void setPixel(int x, int y, Uint8 R, Uint8 G, Uint8 B)
  217. {
  218. Uint8* pixelAddress = getPixelAddress(x, y);
  219. if (pixelAddress)
  220. {
  221. Uint32 pixel = SDL_MapRGB(screen->format, R, G, B);
  222.  
  223. switch(screen->format->BytesPerPixel)
  224. {
  225. case 1: //8-bit
  226. *pixelAddress = pixel;
  227. break;
  228.  
  229. case 2: //16-bit
  230. *(Uint16*)pixelAddress = pixel;
  231. break;
  232.  
  233. case 3: //24-bit
  234. if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
  235. {
  236. pixelAddress[0] = (pixel >> 16) & 0xff;
  237. pixelAddress[1] = (pixel >> 8) & 0xff;
  238. pixelAddress[2] = pixel & 0xff;
  239. }
  240. else
  241. {
  242. pixelAddress[0] = pixel & 0xff;
  243. pixelAddress[1] = (pixel >> 8) & 0xff;
  244. pixelAddress[2] = (pixel >> 16) & 0xff;
  245. }
  246. break;
  247. case 4: //32-bit
  248. *(Uint32*)pixelAddress = pixel;
  249. break;
  250. }
  251. }
  252. /* update the screen (aka double buffering) */
  253. }
  254.  
  255. void setPixel(int x, int y, SDL_Color color)
  256. {
  257. setPixel(x, y, color.r, color.g, color.b);
  258. }
  259.  
  260. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// TODO:
  261.  
  262. struct pix
  263. {
  264. int color;
  265. int times;
  266. };
  267.  
  268.  
  269.  
  270. void Sortowanie( pix tab[], int size = 256)
  271. {
  272. for( int i = 0; i < size; ++i )
  273. {
  274. for( int j = 0; j < size - 1; ++j )
  275. {
  276. if( tab[j].times < tab[j + 1].times )
  277. swap( tab[j], tab[j + 1]);
  278.  
  279. }
  280. }
  281. }
  282.  
  283.  
  284. void Funkcja1()
  285. {
  286. int halveW = width/2;
  287. int halveH = height/2;
  288. pix countR[256];
  289. for(int i=0; i<256; ++i)
  290. {
  291. countR[i].color = i;
  292. countR[i].times = 0;
  293. }
  294. // TODO: but without plagiarism!
  295. for(int y=0; y<halveH; ++y)
  296. {
  297. for(int x=0; x<halveW; ++x)
  298. {
  299. SDL_Color newColor;
  300. newColor = getPixel(x,y);
  301. ++countR[newColor.r].times;
  302. }
  303. }
  304. //zliczenie ile jest kolorow na obrazku o danej skladowej R
  305. int numberOfColors = 0;
  306. for(int i=0; i<256; ++i)
  307. {
  308. if(countR[i].times > 0)
  309. ++numberOfColors;
  310. }
  311. cout << "W obrazku wystepuje " << numberOfColors << " roznych kolorow" << endl;
  312.  
  313. Sortowanie(countR);
  314. cout << "Najczesciej wystepuja: " << endl;
  315. if(numberOfColors < 7)
  316. {
  317. for(int i = 0; i<numberOfColors; ++i)
  318. cout << countR[i].color << " wystepuje " << countR[i].times << " razy" << endl;
  319. }
  320. else
  321. {
  322. for(int i=0; i<7; ++i)
  323. cout << countR[i].color << " wystepuje " << countR[i].times << " razy" << endl;
  324. }
  325.  
  326. for(int y=0; y<halveH; ++y)
  327. {
  328. for(int x=0; x<halveW; ++x)
  329. {
  330. SDL_Color currentColor;
  331. currentColor = getPixel(x,y);
  332. int bestColor = countR[0].color;
  333. int distance = abs(currentColor.r - countR[0].color);
  334. for(int i=1; i<7; ++i)
  335. {
  336. int newDistance = abs(currentColor.r - countR[i].color);
  337. if( newDistance < distance)
  338. {
  339. distance = newDistance;
  340. bestColor = countR[i].color;
  341. }
  342. }
  343. currentColor.r = bestColor;
  344. setPixel(halveW+x,y, currentColor);
  345. }
  346. }
  347. SDL_Flip(screen);
  348. }
Advertisement
Add Comment
Please, Sign In to add comment