Что делает LockBits/UnlockBits в С#?

У меня есть метод в С#, который делает только свои LockBits, а затем UnlockBits, а изображения (ввод/вывод, преобразованные в байтовые массивы) разные. Тот, что на выходе, имеет меньше 100 с чем-то байтов, чем тот, что на входе. Это происходит только с файлами .jpg. И проверив файлы в HxD я пришел к пониманию что это удаление части шапки, точнее подписи exif. Но я не знаю, как и почему.

Кто-нибудь знает, что это делает?

Вот код:

public Image Validate (image){
  BitmapData original = null;
  Bitmap originalBMP = null;
  try{
     originalBMP = image as Bitmap;
     original = originalBMP.LockBits(new Rectangle(0, 0, 
        originalBMP.Width, originalBMP.Height),
        ImageLockMode.ReadWrite,
        originalBMP.PixelFormat);
     originalBMP.UnlockBits(original);
  }catch{}

  return image;
}

person jlnc    schedule 21.01.2020    source источник
comment
LockBits блокирует доступ к битам растрового изображения, но не изменяет их. Что касается EXIF ​​- ваш код не загружает и не сохраняет данные EXIF. Он работает с несжатыми растровыми данными, которые могут быть получены или не получены из файла, содержащего данные EXIF. Ваш код сохранения преобразует эти растровые данные в JPG и сохраняет данные EXIF.   -  person Panagiotis Kanavos    schedule 21.01.2020


Ответы (2)


Вызов Bitmap.LockBits() с последующим Bitmap.UnlockBits() ничего не делает.

Поведение, которое вы наблюдаете, связано с загрузкой изображения JPEG, а затем его повторным сохранением. JPEG использует алгоритм с потерями. Итак, что происходит:

  1. Вы загружаете JPEG с диска
  2. Данные JPEG декодируются в отдельные пиксели с информацией о цвете, то есть в растровое изображение.
  3. Вы снова сохраняете растровое изображение в формате JPEG, в результате чего получается файл, отличный от #1.

При этом вы также можете потерять метаданные, которые присутствовали в файле JPEG. Так что да, файл другой и, вероятно, меньшего размера, потому что каждый раз, когда вы это делаете, вы теряете некоторые пиксельные данные или метаданные.

Биты блокировки/разблокировки используются, чтобы позволить программе манипулировать данными изображения в памяти. Ни больше ни меньше. См. также документацию для тех, методы.

person CodeCaster    schedule 21.01.2020

Используйте метод LockBits для блокировки существующего растрового изображения в системной памяти, чтобы его можно было изменить программно. Вы можете изменить цвет изображения с помощью метода SetPixel, хотя метод LockBits предлагает более высокую производительность для крупномасштабных изменений. Структура Rectangle, указывающая блокируемую часть растрового изображения.

Пример: private void LockUnlockBitsExample(PaintEventArgs e) {

    // Create a new bitmap.
    Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");

    // Lock the bitmap's bits.  
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    System.Drawing.Imaging.BitmapData bmpData =
        bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
        bmp.PixelFormat);

    // Get the address of the first line.
    IntPtr ptr = bmpData.Scan0;

    // Declare an array to hold the bytes of the bitmap.
    int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
    byte[] rgbValues = new byte[bytes];

    // Copy the RGB values into the array.
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

    // Set every third value to 255. A 24bpp bitmap will look red.  
    for (int counter = 2; counter < rgbValues.Length; counter += 3)
        rgbValues[counter] = 255;

    // Copy the RGB values back to the bitmap
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

    // Unlock the bits.
    bmp.UnlockBits(bmpData);

    // Draw the modified image.
    e.Graphics.DrawImage(bmp, 0, 150);

}    
person Syed Munawar Hussain    schedule 21.01.2020
comment
Вы можете изменить цвет изображения с помощью метода SetPixel, хотя метод LockBits обеспечивает более высокую производительность На самом деле каждый вызов Get/SetPixel выполняет Lockbits за кулисами, отсюда и плохой perfromanxw. - person TaW; 21.01.2020
comment
Вы отвечаете на вопрос, что можно сделать с LockBits/UnlockBits, и скопировали пример MSDN, но, похоже, вы упускаете суть вопроса. - person CodeCaster; 21.01.2020