2017-01-05 2 views
-1

Я просто хочу сказать, что я новичок в C. Хорошо, с этой точки зрения мое задание на рождественский перерыв состояло в том, чтобы создать программу, которая манипулирует изображением PNG в различных пути. Я сделал большую часть этого, но у меня возникла проблема при попытке написать программу, которая должна увеличить изображение. Я пробовал, и я получил что-то вниз. Хотя я уверен, что это все неправильно ...C - Изменить размер/увеличить изображение

void enlargeImage(Image plain, char *imageInput[]) 
{ 

Image tempImage; 
Pixel** pixels; 

int scale = 2; 

pixels = malloc(plain.height * sizeof(Pixel*) *scale); 

for (int i = 0; i < plain.height; i++) 
{ 
    pixels[i] = malloc(plain.width * sizeof(Pixel*) * scale); 
} 

tempImage.pixels = pixels; 
tempImage.height = plain.height * scale; //Can I even do this?? Or is it completely wrong? 
tempImage.width = plain.width * scale; 

// I've tried a few variations of this code 
for (int height = 0; height < plain.height; height++) 
{ 

    for (int width = 0; width < plain.width; width++) 
    { 

      tempImage.pixels[height][width] = plain.pixels[height][width]; 

    } 
} 



writeImage(imageInput, &tempImage); //This is a function written by my teachers. This is also where I get an error. I'm suspecting it's because I've doubled the size of tempImage ?? 

free(tempImage.pixels); 
} 

Я был бы очень признателен, если кто-то может помочь мне ^^
Спасибо!

+0

Распределение памяти вашего нового масштабированного изображения выглядит правильно. Неправильное назначение пикселей, хотя в цикле. Вы повторяете старый размер и устанавливаете только исходные пиксели изображения в масштабированном. Вы должны реализовать механизм для интерполяции исходных значений в новые позиции масштабированного изображения. Так как масштаб равен 2, вы можете сделать это для каждого второго пикселя строки изображения. –

+0

Прошу прощения, но мы отвечаем на вопросы о конкретных проблемах программирования. Проверьте свою программу. Если это на самом деле неправильно, тогда приложите все усилия, чтобы выяснить проблему самостоятельно, прежде чем принести нам это конкретное проступка. –

+0

@GregK. О, хорошо. Спасибо C: – Eva

ответ

0

1. Распределение должно быть так:

tempImage.height = plain.height * scale; 
tempImage.width = plain.width * scale; 

pixels = malloc(tempImage.height * sizeof(Pixel*)); 
if (pixels == NULL) return; 

for (int i = 0; i < tempImage.height; i++) 
{ 
    pixels[i] = malloc(tempImage.width * sizeof(Pixel)); 
    if (pixels[i] == NULL) 
    { 
     for (int j = 0; j < i; j++) free(pixels[j]); 
     free(pixels); 
     return; 
    } 
} 

tempImage.pixels = pixels; 

Очки:

  • Избегайте делать пару умножений дважды, вычисляя tempImage.height и tempImage.width, прежде чем делать распределение.
  • Хотя sizeof(char) определен в 1, и поэтому его умножение не является вредным, это создает путаницу и делает чтение программы сложнее.
  • Тип элементов pixels[i]: Pixel. поэтому sizeof(Pixel) следует умножить вместо sizeof(Pixel*) во втором malloc().
  • Выделить память для всех строк. Ваша программа выделяла только первую половину строк.
  • Возвращаемых значения malloc() должны быть проверены, чтобы избежать разыменований NULL, который возвращается из malloc(), когда он выходит из строя, и вызова неопределенного поведения.

2. Преобразование должно быть, как это:

for (int height = 0; height < tempImage.height; height++) 
{ 
    for (int width = 0; width < tempImage.width; width++) 
    { 
     tempImage.pixels[height][width] = plain.pixels[height/scale][width/scale]; 
    } 
} 

Очки:

  • Установка значений для всех пикселей целевого изображения (tempImage). Начальные значения буфера, выделенного через malloc(), являются неопределенными, и с их помощью будет вызываться неопределенное поведение.
  • Будьте осторожны, чтобы не получить доступ (без чтения или записи) вне диапазона массивов, или вы будете вызывать неопределенное поведение.

3. Вы освободив список строк по free(tempImage.pixels);, но вы должны освободить данные каждой строки путем добавления

for (int i = 0; i < tempImage.height; i++) 
{ 
    free(tempImage.pixels[i]); 
} 

просто перед тем линии free(tempImage.pixels);. Обратите внимание, что tempImage.pixels и pixels указывают на один и тот же массив, поэтому вам не нужно (и не должно) использовать free() для обоих из них: используйте free() только для одного из них.

4. Не зная фактическую подпись writeImage, convination из

void enlargeImage(Image plain, char *imageInput[]) 

и

writeImage(imageInput, &tempImage); 

выглядит странно. Вы уверены, что первый аргумент writeImage должен быть указателем на указатель на символы, а не указателем на такие символы, как char *imageInput?

+0

Прежде всего, большое вам спасибо за помощь и объяснение каждого шага. Я многому научился, что мой профессор коллажа никогда не упоминал в классе. Что касается аргумента в 'writeImage', я думаю, что это должно быть? Как я уже упоминал в моем коде выше, это функция, написанная моими профессорами, которую я назвал (??) в моем «int main()», а затем в моих собственных письменных функциях. AKA есть 3 разных файла c (я надеюсь, что это имело какой-то смысл). – Eva

Смежные вопросы