Edycja zdjęcia z poziomu innej formatki

0

Witam

Piszę na zaliczenie program graficzny, który umożliwia edytowanie zdjęć. Postanowiłem robić to na osobnych formatkach i mam z tym pewien problem. otóż po naciśnięciu przycisku "jasność" pojawia się Form4 wywołuję to z poziomu Form1 za pomocą takiego kodu:

 Form4 form4 = new Form4(this);
            form4.Owner = this;
            form4.ShowDialog();

W Form1 znajduje sie obiekt pictureBox1 który wyświetla aktualne zdjecie. i teraz po uruchomieniu Form4, chciałbym za pomocą suwaka zmieniać jasność zdjęcia w Form1.

oto kod Form4:

namespace WindowsFormsApplication1
{
    public partial class Form4 : Form
    {
        Form1 form1;




        public Form4(Form1 form1)
        {
            InitializeComponent();
        }

        public void ApplyBrightness(int brightness)
        {
            int A, R, G, B;
            Color pixelColor;
            Bitmap bmpPo = new Bitmap(form1.pictureBox1.Image);


            for (int y = 0; y < bmpPo.Height; y++)
            {
                for (int x = 0; x < bmpPo.Width; x++)
                {
                    pixelColor = bmpPo.GetPixel(x, y);
                    A = pixelColor.A;
                    R = pixelColor.R + brightness;
                    if (R > 255)
                    {
                        R = 255;
                    }
                    else if (R < 0)
                    {
                        R = 0;
                    }

                    G = pixelColor.G + brightness;
                    if (G > 255)
                    {
                        G = 255;
                    }
                    else if (G < 0)
                    {
                        G = 0;
                    }

                    B = pixelColor.B + brightness;
                    if (B > 255)
                    {
                        B = 255;
                    }
                    else if (B < 0)
                    {
                        B = 0;
                    }

                    bmpPo.SetPixel(x, y, Color.FromArgb(A, R, G, B));
                }
            }
            form1.pictureBox1.Image = bmpPo;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Close(); 
        }


        private void trackBar1_Scroll(object sender, EventArgs e)
        {

          
        }

        private void button2_Click(object sender, EventArgs e)
        {


            ApplyBrightness(trackBar1.Value);
        }


    }
}

Niestety przy uruchomieniu programu nie wywala żadnego błędu, jednak gdy dojdzie do wykonania funkcji ApplyBrightness wywala program i w VisualStudio przy lini:

Bitmap bmpPo = new Bitmap(form1.pictureBox1.Image); 

Pojawia się błąd Object reference not set to an instance of an object.

Niestety nie wiem jak sobie z tym poradzić wydaje mi się że prawidłowo dziedziczę pole pictureBox1 do tego na tym polu mam ustawione Modifers na Public

0

Pole form1 w klasie Form4 jest nullem.
Poza tym, zacznij sensownie nazywać klasy, kontrolki, zmienne, pola.. Zacznij wszystko sensownie nazywać, bo nazwa button1, pictureBox1 to nie są żadne nazwy.

0
stfu napisał(a):

Pole form1 w klasie Form4 jest nullem.
Poza tym, zacznij sensownie nazywać klasy, kontrolki, zmienne, pola.. Zacznij wszystko sensownie nazywać, bo nazwa button1, pictureBox1 to nie są żadne nazwy.

No tak tyle że do innej formatki z która generuje histogram wszystko działa prawidłowo.

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        Form1 form1;




        public Form2(Form1 form1)
        {
            InitializeComponent();
            form1.progressBar1.Visible = true;
            form1.progressBar1.MarqueeAnimationSpeed = 50;
            form1.progressBar1.Maximum = form1.pictureBox1.Image.Width;
            form1.progressBar1.Value = 0;

            Bitmap bmpHistogram = new Bitmap(pbHistogram1.Width,
pbHistogram1.Height);
            Bitmap bmpPrzed = new Bitmap(form1.pictureBox1.Image);

            int[] tablica = new int[256];

            int max = 0;

            for (int x = 0; x < form1.pictureBox1.Image.Width; x++)
            {
                form1.progressBar1.Increment(1);

                for (int y = 0; y < form1.pictureBox1.Image.Height; y++)
                {
                    // liczymy ilosc kolorow
                    Color cPixel = bmpPrzed.GetPixel(x, y);
                    int srednia = (cPixel.B + cPixel.G + cPixel.R) /3;

                    tablica[srednia]++;
                }
            }

            for (int i = 0; i < 256; i++)
            {
                if (tablica[i] > max)
                {
                    max = tablica[i];
                }
            }

            Graphics g;
            g = Graphics.FromImage(bmpHistogram);
            g.FillRectangle(Brushes.White, 0, 0, bmpHistogram.Width,bmpHistogram.Height);

            double Procent = max / bmpHistogram.Height;
            double IlePx = bmpHistogram.Height * bmpHistogram.Width;
            for (int i = 0; i < 256; i++)
            {
                float secondHeight = bmpHistogram.Height - (float)(tablica[i] / Procent);

                Pen myPen = new Pen(System.Drawing.Color.Black, 2);
                g.DrawLine(myPen, i*2, form1.pictureBox1.Image.Height, i*2, secondHeight);
                pbHistogram1.Image = bmpHistogram;
                pbHistogram1.Invalidate();
            }

            form1.progressBar1.Value = 0;
            form1.progressBar1.Visible = false;
    

        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Close(); 

        }


      



    }
}

więc nie bardzo rozumiem dlaczego w tym przykładzie pobieram z pictureBox1 bitmape do wygenerowania histogramu i jest ok, a w drugim przypadku pobieram do Form4 i już są jakieś problemy.

1

Nie bardzo rozumiesz, bo nie znasz podstaw. Tam gdzie generujesz histogram masz konstruktor, którzy przyjmuje obiekt Form1. Jak wywołasz sobie z jakiegoś miejsca w klasie Form1 taki kod:

Form2 histogram = new Form2(this);

, to wtedy będzie ok, bo pod zmienną form1 w KONSTRUKTORZE będzie obiekt, który odpowiada za formę Form1. Później to ucieka, znika, ginie. Jednym słowem, nie masz do niego później dostępu.

Jak to rozwiązać? W konstruktorze formy, która przyjmuje obiekt innej formy, przypisać do pola tego samego typu, który dostajesz w konstruktorze, referencję do tego obiektu.
Zresztą. Masz w kodzie takie pole klasy, ale go nie używasz. To się samo nie przypisze.

Robisz tak:

public Form4(Form1 form1)
{
	InitializeComponent();
	this.form1 = form1;
}

I będzie ok.

Do zmiany pozostaje:

  1. Nazwy zmiennych, o których pisałem wyżej.
  2. Konstruktor, jak sama nazwa wskazuje, ma za zadanie konstruować obiekt. Nic nie ma rysować, wykonywać zaawansowanych obliczeń itd. Zatem to co robi konstruktor w Form2 powinna robić jakaś metoda. Czy to reagująca na jakieś zdarzenie, czy to wywoływana "z palca".
0

Dzięki wszystko działa prawidłowo ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1