Скопируйте байты в памяти в массив в VB.NET - PullRequest
2 голосов
/ 13 ноября 2009

К сожалению, я не могу прибегнуть к C # в моем текущем проекте, поэтому мне придется решить эту проблему без ключевого слова unsafe .

У меня есть растровое изображение, и мне нужен прямой доступ к пикселям и значениям канала. Я хотел бы выйти за рамки Marshal.ReadByte () и Marshal.WriteByte () (и определенно за пределы GetPixel и SetPixel).

Есть ли способ поместить все пиксельные данные растрового изображения в байтовый массив, который работает как в 32-, так и в 64-битных системах? Я хочу точно такой же макет, как и в исходном растровом изображении, поэтому также необходимо добавить отступы для каждой строки (если она существует).

У маршала, похоже, нет ничего похожего на:

byte[] ReadBytes(IntPtr start, int offset, int count)

Если я полностью не пропустил это ...

Любая помощь с благодарностью, David

пс. Пока все мои изображения в формате пикселей 32BppPArgb.

Ответы [ 4 ]

2 голосов
/ 13 ноября 2009

У маршала есть метод, который делает именно то, что вы просите. См. Marshall.Copy ()

public static void Copy(
    IntPtr source,
    byte[] destination,
    int startIndex,
    int length
   )

Копирует данные из неуправляемой памяти указатель на управляемый 8-битный без знака целочисленный массив.

И есть перегрузки, чтобы идти в другом направлении

1 голос
/ 13 ноября 2009

shf301 - это то, что нужно, но я хотел бы добавить ссылку на подробное объяснение / руководство по быстрому доступу к пиксельным данным. Вместо сохранения изображения в поток и доступа к файлу в памяти, было бы лучше заблокировать растровое изображение, скопировать пиксельные данные, получить к ним доступ и скопировать их обратно. Производительность этого метода довольно хорошая.

Код написан на c #, но подход не зависит от языка и легко читается.

http://ilab.ahemm.org/tutBitmap.html

1 голос
/ 13 ноября 2009

Будет ли что-то подобное делать? (Непроверенные):

Public Shared Function BytesFromBitmap(ByVal Image As Drawing.Bitmap) As Byte()
   Using buffer As New IO.MemoryStream()
        image.Save(result, Drawing.Imaging.ImageFormat.Bmp)

        Using rdr As New IO.BinaryReader(buffer)
            Return rdr.ReadBytes(buffer.Length)
        End Using
    End Using
End Function

Он не позволит вам напрямую манипулировать пикселями в объекте Drawing.Bitmap, но позволит скопировать это растровое изображение в байтовый массив в соответствии с заголовком вопроса.

Другим вариантом является сериализация через BinaryFormatter, но я думаю, что вам все равно потребуется передать его через MemoryStream.

1 голос
/ 13 ноября 2009

VB не предлагает методы прямого доступа к памяти. У вас есть два варианта:

  1. Используйте маршала класса
  2. Напишите небольшую небезопасную библиотеку C # (или C ++ / CLI), которая обрабатывает только эти операции и ссылается на нее из кода VB.

Хорошо, есть третий вариант. VB.Net по своей природе не поддерживает прямой доступ к памяти, но это может быть достигнуто. Это просто безобразно и подвержено ошибкам. Тем не менее, если вы готовы приложить усилия, вы можете попробовать создать библиотеку доступа к растровым изображениям, используя эти методы в сочетании с подходом, на который ссылались ранее.

...