Wpf képet fekete-fehérré
2015-05-05T17:36:03+02:00
2015-05-06T12:11:21+02:00
2022-08-09T14:28:11+02:00
7563604
Sziasztok!

Egy image vezérlőbe betöltök egy képet dialógus ablakban:

OpenFileDialog op = new OpenFileDialog(); op.Title = "Select a picture"; op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" + "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" + "Portable Network Graphic (*.png)|*.png"; //op.Filter = "bmp files (*.bmp)|*.bmp"; if (op.ShowDialog() == true) { image.Source = new BitmapImage(new Uri(op.FileName)); }
Majd pedig azt szeretném, hogy a képet fekete-fehérré varázsoljam, neten találtam pár algoritmust, de az BitmapImage helyett Bitmap osztállyal dolgozik. 
A BitmapImage a using System.Windows.Media.Imaging; névtérben van.

A bitmap hoz pedig a using System.Drawing; névtérben dolgozik, és még hozzá kell adni a megfelelő

drawing.dll-t.

Azt szeretném megoldani, hogy a BitmapImageben betöltött képet, elösször fekete fehérré tegyem, majd megjelenítsem az Image vezérlővel a wpf ablakban. A háttérben pedig szeretném a fekete fehér képet egy 0-1 -ből álló bináris sorozattá alakítani, további feldolgozás céljából.
Ötletek?
Mutasd a teljes hozzászólást!
Ha feket-fehéren a feketét és fehéret érted, akkor ehhez hasonló kód kell:

FormatConvertedBitmap fcbm = new FormatConvertedBitmap(); fcbm.BeginInit(); fcbm.Source = new BitmapImage(new Uri(op.FileName)); fcbm.DestinationFormat = PixelFormats.BlackWhite; fcbm.EndInit(); image.Source = fcbm; int stride = (fcbm.PixelWidth + 31) / 32 * 32 / 8; byte[] a = new byte[stride * fcbm.PixelHeight]; fcbm.CopyPixels(a, stride, 0);
Gondolom a tömbben lévő bájtokból már nem probléma feldolgozni a biteket:)
Mutasd a teljes hozzászólást!

  • Ez alapján a ColorMatrix használatával tudod gyorsan, kevés kóddal, de kicsit összetetten megoldani a problémát.

    public static Bitmap MakeGrayscale3(Bitmap original) { //create a blank bitmap the same size as original Bitmap newBitmap = new Bitmap(original.Width, original.Height); //get a graphics object from the new image Graphics g = Graphics.FromImage(newBitmap); //create the grayscale ColorMatrix ColorMatrix colorMatrix = new ColorMatrix( new float[][] { new float[] {.3f, .3f, .3f, 0, 0}, new float[] {.59f, .59f, .59f, 0, 0}, new float[] {.11f, .11f, .11f, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 1} }); //create some image attributes ImageAttributes attributes = new ImageAttributes(); //set the color matrix attribute attributes.SetColorMatrix(colorMatrix); //draw the original image on the new image //using the grayscale color matrix g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes); //dispose the Graphics object g.Dispose(); return newBitmap; }
    Mutasd a teljes hozzászólást!
  • Ha feket-fehéren a feketét és fehéret érted, akkor ehhez hasonló kód kell:

    FormatConvertedBitmap fcbm = new FormatConvertedBitmap(); fcbm.BeginInit(); fcbm.Source = new BitmapImage(new Uri(op.FileName)); fcbm.DestinationFormat = PixelFormats.BlackWhite; fcbm.EndInit(); image.Source = fcbm; int stride = (fcbm.PixelWidth + 31) / 32 * 32 / 8; byte[] a = new byte[stride * fcbm.PixelHeight]; fcbm.CopyPixels(a, stride, 0);
    Gondolom a tömbben lévő bájtokból már nem probléma feldolgozni a biteket:)
    Mutasd a teljes hozzászólást!
  • Mindkettőtöknek köszönöm a választ!

    3Ducker itt wpfben Bimaphoz használni kell a System.Drawing; névteret, és mint rájöttem ez nagy kavarodást okoz wpf-ben,  így nem tudom használni a megoldásod.


    ValakiMás megoldását már csak kicsit kellett kiegészíteni, hogy ne dobjon hibát, köszi a segítséget:

    FormatConvertedBitmap fcbm = new FormatConvertedBitmap(); OpenFileDialog op = new OpenFileDialog(); op.Title = "Select a picture"; op.Filter = "bmp files (*.bmp)|*.bmp"; if (op.ShowDialog() == true) { fcbm.BeginInit(); fcbm.Source = new BitmapImage(new Uri(op.FileName)); fcbm.DestinationFormat = PixelFormats.BlackWhite; fcbm.EndInit(); } image.Source = fcbm; int stride = (fcbm.PixelWidth + 31) / 32 * 32 / 8; byte[] a = new byte[stride * fcbm.PixelHeight]; fcbm.CopyPixels(a, stride, 0);
    Tudnál nekem írni róla hogy hogy működik ez a rész, miért ezekkel a számokkal ?
    (fcbm.PixelWidth + 31) / 32 * 32 / 8;
    Mutasd a teljes hozzászólást!
  • A stride az egy sor mérete bájtokban és néggyel oszthatónak kell lennie.
    A +31,/32,*32 azért kell hogy megkapd egy sor méretét bitekben 32 bites határra kerekítve, a /8 meg azért, hogy bájtokban kapd meg - mivel 8 pixel egy bájt mono kép esetén.

    Lehet, hogy ezt is ki lehetne nyerni valahonnan/valahogy, de az részletkérdés.
    Mutasd a teljes hozzászólást!
  • Köszönöm!
    Mutasd a teljes hozzászólást!
abcd