public static Image getJpgThumbnailFromNEF(string filename) { byte[] imgData = extractJpegFromRaw(filename); if (imgData != null) { MemoryStream stream = new MemoryStream(); stream.Write(imgData, 0, imgData.Length); Image myImage = Image.FromStream(stream); Bitmap resizedImage = ResizeImage(myImage, THUMB_WIDTH, THUMB_HEIGHT); Rectangle rect = new Rectangle(0, 0, resizedImage.Width, resizedImage.Height); System.Drawing.Imaging.BitmapData bmpData = resizedImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, resizedImage.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = Math.Abs(bmpData.Stride) * resizedImage.Height; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); // Find min max values byte min = 0xFF; byte max = 0; int[] totalLumin = new int[] { 0, 0, 0 }; for (int i = 0; i < bytes; i += 4) { if (rgbValues[i] < min) { min = rgbValues[i]; } if (rgbValues[i] > max) { max = rgbValues[i]; } if (rgbValues[i + 1] < min) { min = rgbValues[i + 1]; } if (rgbValues[i + 1] > max) { max = rgbValues[i + 1]; } if (rgbValues[i + 1] < min) { min = rgbValues[i + 1]; } if (rgbValues[i + 1] > max) { max = rgbValues[i + 1]; } totalLumin[0] += (int)rgbValues[i + 0]; totalLumin[1] += (int)rgbValues[i + 1]; totalLumin[2] += (int)rgbValues[i + 2]; } for (int i = 0; i < 3; i++) { totalLumin[i] /= (bytes / 4); } int totalAverage = (totalLumin[0] + totalLumin[1] + totalLumin[2]) / 3; float grayContrastFactor = 127.0f / (float)totalAverage; byte[] contrastLUT = new byte[256]; for (int i = 0; i < totalAverage; i++) { contrastLUT[i] = (byte)((float)i * (grayContrastFactor * (float)i / (float)totalAverage + 1.0f * (float)(totalAverage - i) / totalAverage)); } for (int i = totalAverage; i < 256; i++) { contrastLUT[i] = (byte)((float)i * (grayContrastFactor * (float)(255 - i) / (float)(255 - totalAverage) + 1.0f * (float)(i - totalAverage) / (float)(255 - totalAverage))); } // Perform level adjustment float r, g, b, h, s, v; for (int i = 0; i < bytes; i += 4) { //if ((i % 2400) < 1200) { r = (float)rgbValues[i + 0] / 255.0f; g = (float)rgbValues[i + 1] / 255.0f; b = (float)rgbValues[i + 2] / 255.0f; ImageProcessing.RGBtoHSV(r, g, b, out h, out s, out v); v = (v * grayContrastFactor > 1.0f ? 1.0f : (v * grayContrastFactor)); ImageProcessing.HSVtoRGB(out r, out g, out b, h, s, v); rgbValues[i + 0] = (byte)(r * 255.0f); rgbValues[i + 1] = (byte)(g * 255.0f); rgbValues[i + 2] = (byte)(b * 255.0f); } } // Copy the RGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); resizedImage.UnlockBits(bmpData); return(resizedImage); } else { return(null); } }