2014-09-16 3 views
1

Я пытаюсь масштабировать изображение с помощью байтового массива. Мой план состоял в том, чтобы использовать ближайшего соседа, чтобы найти пиксельные данные для нового байтового массива, но у меня возникают некоторые проблемы, преобразующие исходные данные моего изображения. srcImage имеет тип Image, и я могу успешно преобразовать его в массив байтов и преобразовать его обратно в изображение, у меня возникла проблема с масштабированием этого изображения с использованием его байтового массива. Я использую MemoryStream (в моем методе byteArrayToImage), чтобы преобразовать trgData обратно в изображение, но я получаю исключение ArguementException, указывающее, что параметр «новый MemoryStream (byteArray)» недействителен.Масштабирование массива байтов изображения через ближайший соседний

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

Вот мой код для копирования и масштабирования данных изображения:

byte[] srcData = ImageToByteArraybyImageConverter(srcImage); 

// data transformations here 
// 
float srcRatio = srcImage.Width/srcImage.Height; 
int bitsPerPixel = ((int)srcImage.PixelFormat & 0xff00) >> 8; 
int bytesPerPixel = (bitsPerPixel + 7)/8; 
int srcStride = 4 * ((srcImage.Width * bytesPerPixel + 3)/4); 

// find max scale value 
int scale = 3; // NOTE: temporary 

// create new byte array to store new image 
int width = srcImage.Width * scale; 
int height = srcImage.Height * scale; 
int stride = width; 
byte[] trgData = new byte[height * stride]; 

// update the progress bar 
progressBar1.Value = 10; 

int i = -1; // index for src data 
// copy pixel data 
for (int n = 0; n < trgData.Length; n++) 
{ 
    if (n % stride == 0) 
    { 
     i++; 
    } 
    trgData[n] = srcData[i]; 
} 

progressBar1.Value = 60; 

// convert the pixel data to image 
Image newImage = byteArrayToImage(trgData); 
progressBar1.Value = 70; 
if (newImage != null) 
{ 
    // save the image to disk 
    newImage.Save(newFileName); 
    progressBar1.Value = 100; 
} 

Позвольте мне знать, если у вас есть какие-либо дополнительные вопросы, и спасибо!

Edited: Вот методы, которые загружаются и сохранить массив байт

private byte[] ImageToByteArraybyImageConverter(System.Drawing.Image image) 
{ 
    ImageConverter imageConverter = new ImageConverter(); 
    byte[] imageByte = (byte[])imageConverter.ConvertTo(image, typeof(byte[])); 
    return imageByte; 
} 


private Image byteArrayToImage(byte[] byteArrayIn) 
{ 
    Image returnImage = null; 
    using (MemoryStream ms = new MemoryStream(byteArrayIn)) 
    { 
     returnImage = Image.FromStream(ms); 
    } 
    return returnImage; 
} 
+0

Я думаю, это будет зависеть от того, как функции 'ImageToByteArraybyImageConverter' читает в изображение. Если он просто открывает файл изображения, а затем считывает байты в массив, тогда массив байтов будет представлять формат файла изображения (.png, .gif, .jpg и т. Д.) – Icemanind

+0

Сейчас я просто использую класс ImageConverter для преобразования изображения в массив байтов. Я действительно не понимаю, какую еще информацию мне нужно, чтобы правильно масштабировать изображение. Я отредактирую вопрос, чтобы отобразить, как я загружаю и сохраняю массив байтов. – leaflet757

+0

Быстрые наблюдения: 'srcImage.Width/srcImage.Height' - целочисленное деление; 'srcStride' не используется. –

ответ

1

Вы делаете очень странную вещь здесь:

int i = -1; // index for src data 
// copy pixel data 
for (int n = 0; n < trgData.Length; n++) 
{ 
    if (n % stride == 0) 
    { 
     i++; 
    } 
    trgData[n] = srcData[i]; 
} 

После каждых width итераций (поскольку stride == width) вы увеличиваете исходный индекс. То есть, вся первая линия нового изображения будет заполнена первым байтом исходного изображения, второй линия - со вторым байтом и т.д.

Попробуйте вместо этого:

int targetIdx = 0; 
for (int i = 0; i < height; ++i) 
{ 
    int iUnscaled = i/scale; 
    for (int j = 0; j < width; ++j) { 
     int jUnscaled = j/scale; 
     trgData[targetIdx++] = srcData[iUnscaled * origWidth + jUnscaled]; 
    } 
} 

Обратите внимание, что принимает BPP = 1, то есть копирует байты evey scale раз по горизонтали и по вертикали. Это не трудно изменить его для БПП более 1.

Here is a demo иллюстрирующих оба алгоритма (комментарий на первую строку, чтобы увидеть, как ведет себя алго)

+0

Спасибо! Теперь я вижу, что копирование данных было неправильным – leaflet757

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

  • Нет связанных вопросов^_^