1

Windows Phone アプリの場合、スライダーで明るさを調整しているときに、右に動かすと正常に動作します。しかし、前の位置に戻ると、画像が暗くなる代わりに、どんどん明るくなります。これがピクセル操作に基づく私のコードです。

private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {

        wrBmp = new WriteableBitmap(Image1, null);


        for (int i = 0; i < wrBmp.Pixels.Count(); i++)
        {
            int pixel = wrBmp.Pixels[i];
            int B = (int)(pixel & 0xFF); pixel >>= 8;
            int G = (int)(pixel & 0xFF); pixel >>= 8;
            int R = (int)(pixel & 0xFF); pixel >>= 8;
            int A = (int)(pixel);

            B += (int)slider1.Value; R += (int)slider1.Value; G += (int)slider1.Value;
            if (R > 255) R = 255; if (G > 255) G = 255; if (B > 255) B = 255;
            if (R < 0) R = 0; if (G < 0) G = 0; if (B < 0) B = 0;
            wrBmp.Pixels[i] = B | (G << 8) | (R << 16) | (A << 24);
        }
        wrBmp.Invalidate();
        Image1.Source = wrBmp;

    }

何が欠けていますか、スライダーの値に問題はありますか。モバイルではいつものように小さな画像を扱っています。元の画像をコピーして複製しようとしました。コードは完璧だと思います。多くの調査の結果、問題はスライダーの値が原因であることがわかりました。考えられる解決策は、スライダーに初期値を割り当てることです。コードのヘルプが必要です。

プライベート ダブル lastSlider3Vlaue; private void slider3_ValueChanged(オブジェクト送信者,`RoutedPropertyChangedEventArgs e) {

        if (slider3 == null) return;
        double[] contrastArray = { 1, 1.2, 1.3, 1.6, 1.7, 1.9, 2.1, 2.4, 2.6, 2.9 };
        double CFactor = 0;
        int nIndex = 0;
        nIndex = (int)slider3.Value - (int)lastSlider3Vlaue;
        if (nIndex < 0)
        {
            nIndex = (int)lastSlider3Vlaue - (int)slider3.Value;
            this.lastSlider3Vlaue = slider3.Value;
            CFactor = contrastArray[nIndex];
        }
        else
        {
            nIndex = (int)slider3.Value - (int)lastSlider3Vlaue;
            this.lastSlider3Vlaue = slider3.Value;
            CFactor = contrastArray[nIndex];
        }

        WriteableBitmap wbOriginal;
        wbOriginal = new WriteableBitmap(Image1, null);
        wrBmp = new WriteableBitmap(wbOriginal.PixelWidth, wbOriginal.PixelHeight);
        wbOriginal.Pixels.CopyTo(wrBmp.Pixels, 0);
        int h = wrBmp.PixelHeight;
        int w = wrBmp.PixelWidth;
        for (int i = 0; i < wrBmp.Pixels.Count(); i++)
        {
            int pixel = wrBmp.Pixels[i];
            int B = (int)(pixel & 0xFF); pixel >>= 8;
            int G = (int)(pixel & 0xFF); pixel >>= 8;
            int R = (int)(pixel & 0xFF); pixel >>= 8;
            int A = (int)(pixel);

            R = (int)(((R - 128) * CFactor) + 128);
            G = (int)(((G - 128) * CFactor) + 128);
            B = (int)(((B - 128) * CFactor) + 128);

            if (R > 255) R = 255; if (G > 255) G = 255; if (B > 255) B = 255;
            if (R < 0) R = 0; if (G < 0) G = 0; if (B < 0) B = 0;
            wrBmp.Pixels[i] = B | (G << 8) | (R << 16) | (A << 24);
        }

        wrBmp.Invalidate();
        Image1.Source = wrBmp;

}

デバッグ後、前方にスライドするとRGB値が連続的に減少することがわかりましたが、後方にスライドすると、増加するはずの場所でも減少します。過去3か月からこれに取り組んでいる私を助けてください。これに加えて、この全体の画像処理を完了する方法についてもアドバイスをください

4

1 に答える 1

1

Your algorithm is wrong. Each time the slider's value changes, you're adding that value to the picture's brightness. What makes your logic flawed is that the value returned by the slider will always be positive, and you're always adding the brightness to the same picture.

So, if the slider starts with a value of 10, I'll add 10 to the picture's brightness.

Then, I slide to 5. I'll add 5 to the previous picture's brightness (the one you already added 10 of brightness to).

Two ways to solve the issue:

  1. Keep a copy of the original picture, and duplicate it every time your method is called. Then add the brightness to the copy (and not the original). That's the safest way.

  2. Instead of adding the new absolute value of the slider, calculate the relative value (how much it changed since the last time the method was called:

    private double lastSliderValue;
    
    private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        var offset = slider1.Value - this.lastSliderValue;
        this.lastSliderValue = slider1.Value;
    
        // Insert your old algorithm here, but replace occurences of "slider1.Value" by "offset"
    }
    

This second way can cause a few headaches though. Your algorithm is capping the RGB values to 255. In those cases, you are losing information and cannot revert back to the old state. For instance, take the extreme example of a slider value of 255. The algorithm sets all the pixels to 255, thus generating a white picture. Then you reduce the slider to 0, which should in theory restore the original picture. In this case, you'll subtract 255 to each pixel, but since every pixel's value is 255 you'll end up with a black picture.

Therefore, except if you find a clever way to solve the issue mentionned in the second solution, I'd recommand going with the first one.

于 2013-05-31T05:57:08.040 に答える