algorytm.org

Implementacja w C#

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Sepia - Implementacja w C#
Ocena użytkownikóww: *****  / 0
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 14 czerwca 2012 21:06
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

sepia/Form1.cs:
//Sepia - efekt starego zdjecia
//(c) 2012 by Tomasz Lubinski
//www.algorytm.org

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing.Imaging;

namespace sepia
{
    public partial class Form1 : Form
    {

        /// <summary>
        /// Obraz zrodlowy i wynikowy
        /// </summary>
        private Image zrodlo;
        private int bytesPerPixel;
        private Obraz wynik;

        /// <summary>
        /// Zainicjuj
        /// </summary>
        public Form1()
        {
            zrodlo = null;
            bytesPerPixel = 0;
            InitializeComponent();
            trackBar1_ValueChanged(null, null);
        }

        /// <summary>
        /// Wczytaj obraz
        /// </summary>
        private void wczytaj_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Title = "Otwórz obraz";
            dlg.Filter = "pliki jpg (*.jpg)|*.jpg|pliki png (*.png)|*.png|wszystkie pliki (*.*)|*.*";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                zrodlo = new Bitmap(dlg.OpenFile());
                bytesPerPixel = Image.GetPixelFormatSize(zrodlo.PixelFormat) / 8;
                wynik = new Obraz();
                wynik.obrazWynikowy.Image = new Bitmap(dlg.OpenFile());
                wynik.obrazWynikowy.Height = wynik.obrazWynikowy.Image.Height;
                wynik.obrazWynikowy.Width = wynik.obrazWynikowy.Image.Width;
                wynik.obrazWynikowy.Refresh();
                wynik.ClientSize = new System.Drawing.Size(wynik.obrazWynikowy.Width + 24, wynik.obrazWynikowy.Height + 32);
                wynik.Show();
                wynik.Refresh();
            }
            dlg.Dispose();
        }

        /// <summary>
        /// Sepia
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBar1_ValueChanged(object sender, EventArgs e)
        {
            //Nie rob nic wiecej jezeli obraz jest jeszcze niewczytany
            if (zrodlo == null)
            {
                return;
            }

            //Sprawdz czy obraz wynikowy bedzie kolorowy
            if (bytesPerPixel < 3)
            {
                MessageBox.Show("Nieprawidłowy format pliku wejściowego");
            }

            //Pobierz wartosc sepii
            int sepia = suwak.Value;

            //Przygotuj tablice LUT dla kanalu R (czerwien)
            byte[] LUTR = new byte[256];
            for (int i = 0; i < 256; i++)
            {
                if (i + 2 * sepia > 255)
                {
                    LUTR[i] = 255;
                }
                else
                {
                    LUTR[i] = (byte)(i + 2 * sepia);
                }
            }

            //Przygotuj tablice LUT dla kanalu G (zielen)
            byte[] LUTG = new byte[256];
            for (int i = 0; i < 256; i++)
            {
                if (i + sepia > 255)
                {
                    LUTG[i] = 255;
                }
                else
                {
                    LUTG[i] = (byte)(i + sepia);
                }
            }

            //Kopiuj obrazek zrodlowy
            Bitmap bitmap = (Bitmap)zrodlo.Clone();
            wynik.obrazWynikowy.Image = bitmap;

            //Pobierz wartosc wszystkich punktow obrazu
            BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
            byte[] pixelValues = new byte[Math.Abs(bmpData.Stride) * bitmap.Height];
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, pixelValues, 0, pixelValues.Length);

            //Sepia dla kazdego punktu obrazu
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    int index = y * bmpData.Stride + x * bytesPerPixel;
                    int val = (int)(0.299 * pixelValues[index + 2] + 0.587 * pixelValues[index + 1] + 0.114 * pixelValues[index]);
                    pixelValues[index + 2] = LUTR[val];
                    pixelValues[index + 1] = LUTG[val];
                    pixelValues[index] = (byte)val;
                }
            }

            //Ustaw wartosc wszystkich punktow obrazu
            System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, bmpData.Scan0, pixelValues.Length);
            bitmap.UnlockBits(bmpData);
        }
    }
}
Dodaj komentarz