IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

> работа с графикой на С
Tan
сообщение 2.10.2007 21:16
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Доброго времени суток. Моя цель : необходимо написать функцию, в которую передаются 5 параметров, первые 4 - координаты изображения, выведенного на экране, последний параметр H - это целое число. Требуется поделить изображение на Н одинаковых квадратов, после чего вывести их в определённом порядке в том же месте, где была изначальная картинка (это часть одной большой задумки). Вероятней всего наиболее удобно будет использовать одномерный массив из Н элементом, состоящих из структуры, которая хранит координаты каждого из маленьких квадратиков, а так же саму маленькую картинку. Вот, с релизацией возникли проблемки. Теперь начну сначала, и первый вопрос : как продефинировать вышеописанную структуру? (с коордианатами ясно, а вот как запихнуть туда ячейку в которой будет хранится небольшое изображение, которое занесётся в память, например, тем же getimage) Спасибо.


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 17)
volvo
сообщение 2.10.2007 21:25
Сообщение #2


Гость






typedef
  struct __IMAGEPART {
    int x_left, y_top;
    int x_right, y_bottom;

    void *buffer; // здесь - указатель на буфер, хранящий собственно изображение
  } IMAGEPART;



(координаты правого нижнего угла хранить не обязательно - они будут содержатся в данных, получаемых getimage)
 К началу страницы 
+ Ответить 
Tan
сообщение 2.10.2007 21:31
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Cпасибо, начну реализовывать, если появятся вопросы, отпишусь.


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 12:49
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Появился следующий вопрос. Допустим на экран выведена картинка плотностью 256 цветов. Занесёт ли getimage в память участок картинки такой плотностью без потерь красок?


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.10.2007 12:55
Сообщение #5


Гость






А функции getimage все равно, сколько у тебя цветов... Она просто
Цитата(help)
saves a bit image of the specified region into memory
... Если восстанавливать будешь в том же видеорежиме - получишь то же изображение...
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 13:25
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Понятно, просто возникла проблема, что putimage выводит ухудшенное изображение, наверно где - то неуловил переход видеорежимов. Здесь прикрплён проект. При запуске, когда появится меню, на кнопке старт при нажатии ентер программа считывает бмп файл, потом вырезает его маленький левый верхний кусочек и выводит его. Но выводит его как я уже отписал ухудшенно. Посмотрите пожалуйста, просто насколько я заметил считывание в память и вывод происходят в одном видеорежиме.


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.10.2007 14:20
Сообщение #7


Гость






Я вообще не понимаю, как твоя программа могла работать... Память-то под буфер ты не выделил... Вот так (здесь нет всех необходимых проверок, это просто пример) попробуй:

void imrand (x1, x2, y1, y2, n) {

  void *buf;
  int storona, i, d, size;
  storona = (x2 - x1) * (y2 - y1) / (n * n); // Зачем это?

  size = imagesize(x1, x2, y1, y2);
  if((buf = malloc(size)) != NULL) {

    getimage (x1, x2, y1, y2, buf);
    cleardevice();
    putimage (50, 50, buf, COPY_PUT);

    free(buf);
  };

}
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 14:29
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Про сторону - это я в будущем буду использовать, чтобы разделить картинку на равные элементы - квадраты. Спасибо за подсказку, сейчас буду разбираться. Да, всё работает, огромное спасибо, я как - то и упустил, что надо память выделять, думал, что этот процесс автоматизирован.

Сообщение отредактировано: Tan - 7.10.2007 14:32


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 15:14
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


У меня снова новый вопрос по данной теме smile.gif Имеется структура, которую помог описать volvo :
typedef
  struct __IMAGEPART {
    int x_left, y_top;
    int x_right, y_bottom;

    void *buffer;
  } IMAGEPART;

Ситуация следующая : в процедуру отсылается занчение (допустим n). После этого необходимо создать двумерный массив из элементов структуры IMAGEPART n X n. То есть по идее
IMAGEPART arr[n][n];
, но компилятор ругается и, насколько я понял, хочет видеть там константые величины, как быть ? При чём заведомо известно, что 1 < n < 5. По идее можно создать 5 массивов и кейсом, в зависимости от n выбрать тот, с которым будет работа, или как в паскале, описать максимально - возможный массив, но работать только с частью (не нравится этот вариант), но возможно есть что - то по логичнее или проще. Спасибо.


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.10.2007 17:23
Сообщение #10


Гость






Цитата
возможно есть что - то по логичнее или проще

Логичнее - динамически выделять память под матрицу:

       IMAGEPART **arr;
       int i;

       arr = (IMAGEPART **)malloc(n * sizeof(IMAGEPART*));
       for(i = 0; i < n; ++i)
         arr[i] = (IMAGEPART *)malloc(n * sizeof(IMAGEPART));
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 18:39
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Понятно. Допустим, уже известно число n (тут оно уже K smile.gif ). Я пытался дописать процедуру так, чтобы всё считалось в структуру и потом так же вывелось обратно, вот что я нахимичил, но это всё выводит только первый кусочек, что же не так ? :
    IMAGEPART picturemas[K][K];

    void *buf[K];
    int a, i, d, size, j, xx1, xx2, yy1, yy2, sum = 0;
    a = (x2 - x1) * (y2 - y1) / (n * n);   //сторона квадрата

//    size = imagesize(x1, x2, y1, y2);
//
//    if((buf = malloc(size)) != NULL)
//  {
//    getimage (x1, x2, y1, y2, buf);
//    cleardevice();
//    putimage (50, 50, buf, COPY_PUT);
//    free(buf);
//  };
	 xx1 = x1;
	 yy1 = y1;
	 xx2 = xx1 + a;
	 yy2 = yy1 - a;
	 for (i = 0; i < (K - 1); i++)
	    {
	      for (j = 0; j < (K - 1); j++)
		{
		  picturemas[i][j].x_left = xx1;
		  picturemas[i][j].x_right = xx2;
		  picturemas[i][j].y_top = yy1;
		  picturemas[i][j].y_bottom = yy2;
		  size =  imagesize (xx1,xx2,yy1,yy2);
		  if ((picturemas[i][j].buffer = malloc(size)) != NULL)
		  getimage(xx1,xx2,yy1,yy2,picturemas[i][j].buffer);
		  xx1 = xx1 + a;
		  xx2 = xx2 + a;

		}
	       yy1 = yy1 - a;
	       yy2 = yy2 - a;
	       xx1 = x1;
	       xx2 = x2;
	    }

	   // Очищаем экран и пытаемся всё вывести как и было до очистки

	   cleardevice();

	   for (i = 0; i < (K - 1); i++)
	       for (j = 0; j < (K - 1); j++)
		 putimage (picturemas[i][j].x_left, picturemas[i][j].y_top, picturemas[i][j].buffer , COPY_PUT);



};


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.10.2007 19:18
Сообщение #12


Гость






Я так и не понял логику твоей программы, но смотри:

...
    const int K = 5; // <--- попробуем запомнить 5*5 квадратов ...
    IMAGEPART picturemas[K][K];

    int a, i, size, j, xx1, xx2, yy1, yy2, sum = 0;

    a = 20; // <--- размером 20 * 20 каждый

    // начиная с позиции (x1, y1)

    xx1 = x1; xx2 = xx1 + a;
    yy1 = y1; yy2 = yy1 + a;

    for (i = 0; i < (K - 1); i++) {
      for (j = 0; j < (K - 1); j++) {
        picturemas[i][j].x_left = xx1;
	picturemas[i][j].x_right = xx2;
	picturemas[i][j].y_top = yy1;
	picturemas[i][j].y_bottom = yy2;
	size = imagesize (xx1,yy1,xx2,yy2); // <--- Во-первых у тебя были перемешаны координаты

        // ну, а во вторых - надо проверять выделена ли память ...
	if ((picturemas[i][j].buffer = malloc(size)) != NULL) {
          // Если она выделена - то "граббить" изображение
  	  getimage(xx1,yy1,xx2,yy2,picturemas[i][j].buffer);

	  xx1 = xx1 + a; xx2 = xx2 + a; // и переходить по оси OX
        }
        else {
          closegraph(); // иначе - выходить (ну, или возвращать код ошибки: не хватает памяти)
          exit(1);
        }

      }
      yy1 = yy1 + a; yy2 = yy2 + a; // тут переходим по OY НИЖЕ (ось OY идет сверху вниз)
      xx1 = x1; xx2 = x1 + a; // и перебрасываемся по OX на начальную позицию (здесь тоже ты ошибался...)
    }

    cleardevice();
    for (i = 0; i < (K - 1); i++)
      for (j = 0; j < (K - 1); j++)
        if(picturemas[i][j].buffer) // эту проверку в принципе теперь можно убрать, но я проверял с ней
	  putimage (picturemas[i][j].x_left, picturemas[i][j].y_top, picturemas[i][j].buffer , COPY_PUT);
...


Вот у меня со значением a = 20 все отработало, а при a = 50 уже программа стала вылетать, по нехватке памяти... Возможно придется перейти в другую модель памяти, возможно - farmalloc вместо malloc спасет ситуацию, но сейчас сам каркас рабочий...
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 19:23
Сообщение #13


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Спасибо! Я продолжаю разбираться!


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Tan
сообщение 7.10.2007 22:58
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Странно получается, данная процедура в конце концов выводит не всё изображение, а только его часть. Кстати, а почему вы взяли сторону именно за 20 ? Для проверки ? Просто, чтобы картинка осталось прежней по размеру вероятно надо взять сторону за (x2 - x1) * (y2 - y1) / (k * k). При чём в таком случае всё равно результирующая картинка маленькая (что - то я опять перемудрил наверно).


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.10.2007 23:12
Сообщение #15


Гость






Цитата
данная процедура в конце концов выводит не всё изображение, а только его часть
Естественно... Я же сказал, что делалась попытка сохранить 5*5 квадратных фрагментов изображения размером 20*20 пикселей, то есть всего - кусок картинки 100*100... При больших размерах программа выходит с нехваткой памяти...

Цитата
чтобы картинка осталось прежней по размеру взять сторону за (x2 - x1) * (y2 - y1) / (k * k)
А с чего ты взял, что при разбивке на одинаковые части прямоугольного изображения у тебя получатся квадраты?

Надо вычислять не одну сторону, а 2. Ширину фрагмента делать: (x2 - x1) / k, а его высоту - (y2 - y1) / k, причем при вызове функции в качестве x1, y1, x2, y2 передавать координаты начала/конца изображения, а не 50/80 как у тебя сейчас...
 К началу страницы 
+ Ответить 
Tan
сообщение 8.10.2007 16:45
Сообщение #16


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Я почему - то возомнил, что моё изображение это большой квадрат (сам не знаю почему). Ваши комментарии абсолютно точны, сейчас изменяю процедуру.


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Tan
сообщение 13.10.2007 12:26
Сообщение #17


Профи
****

Группа: Пользователи
Сообщений: 559
Пол: Мужской
Реальное имя: Бруно

Репутация: -  10  +


Вот, используя все ваши замечания я немного изменил функцию, но в таком случае ничего не выводится кроме чёрного экрана, хотя вроде программа не виснет ( K = 5; n = 5; );
IMAGEPART picturemas[K][K];
    int a, i, size, j, xx1, xx2, yy1, yy2, b;
    a = (x2 - x1) / n;   //side by x
    b = (y2 - y1) / n;   //side by y
    xx1 = x1; xx2 = xx1 + a;   // 1st cells position
    yy1 = y1; yy2 = yy1 + b;
    for (i = 0; i < (K - 1); i++)
    {
      for (j = 0; j < (K - 1); j++)
      {
	picturemas[i][j].x_left = xx1;
	picturemas[i][j].x_right = xx2;
	picturemas[i][j].y_top = yy1;
	picturemas[i][j].y_bottom = yy2;
	size = imagesize (xx1,yy1,xx2,yy2); // <--- Во-первых у тебя были перемешаны координаты
	// ну, а во вторых - надо проверять выделена ли память ...
	if ((picturemas[i][j].buffer = malloc(size)) != NULL) {
	  // Если она выделена - то "граббить" изображение
	  getimage(xx1 ,yy1, xx2, yy2, picturemas[i][j].buffer);
	  xx1 = xx1 + a; xx2 = xx2 + a; // и переходить по оси OX
	}
	else {
	  closegraph(); // иначе - выходить (ну, или возвращать код ошибки: не хватает памяти)
	  exit(1);
	}

      }
      yy1 = yy1 + b; yy2 = yy2 + b; // тут переходим по OY НИЖЕ (ось OY идет сверху вниз)
      xx1 = x1;      xx2 = x1 + a; // и перебрасываемся по OX на начальную позицию (здесь тоже ты ошибался...)
    }
    cleardevice();
    for (i = 0; i < (K - 1); i++)
      for (j = 0; j < (K - 1); j++)
	if(picturemas[i][j].buffer) // эту проверку в принципе теперь можно убрать, но я проверял с ней
	  putimage (picturemas[i][j].x_left, picturemas[i][j].y_top, picturemas[i][j].buffer , COPY_PUT);



Сообщение отредактировано: Tan - 13.10.2007 12:27


--------------------
Цитата
Imagination is more important than knowledge.
Albert Einstein
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 13.10.2007 12:33
Сообщение #18


Гость






Чему равно K?

(Программа и не будет виснуть, она просто завершится при невозможности выделения памяти и все... Кстати, зачем ты удалил проект? Как теперь я могу проверить работу твоей функции?)
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 29.07.2025 17:00
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"