计算像素索引时索引越界

时间:2015-03-19 21:32:21

标签: c# image-processing windows-phone-8.1

我的图像裁剪应用基于: http://www.c-sharpcorner.com/UploadFile/55275a/windowsphone-image-crop-with-rectangle/

我稍微修改了一下,所以我可以调整矩形大小而不是创建新的

所以我的整个方法看起来像:

private async void Accept_Click(object sender, EventArgs e)
{
    WriteableBitmap wb = new WriteableBitmap(image);

    double originalImageWidth = wb.PixelWidth;
    double originalImageHeight = wb.PixelHeight;

    double displayedWidth = image1.ActualWidth;
    double displayedHeight = image1.ActualHeight;

    double widthRatio = originalImageWidth / displayedWidth;
    double heightRatio = originalImageHeight / displayedHeight;

    r = (Rectangle) (from c in LayoutRoot.Children 
                     where c.Opacity == .5 select c).First();

    GeneralTransform gt = r.TransformToVisual(LayoutRoot);
    Point p = gt.Transform(new Point(0, 0));

    Point1 = (r.TransformToVisual(this)).Transform(new Point(0, 0));
    Point2 = new Point(Point1.X + r.Width, Point1.Y + r.Height);

    WriteableBitmap newImage = new WriteableBitmap(
        (int) (widthRatio * Math.Abs(Point2.X - Point1.X)),
        (int) (heightRatio * Math.Abs(Point2.Y - Point1.Y)));

    int xoffset = (int) (((Point1.X < Point2.X) ? Point1.X : Point2.X) * widthRatio);
    int yoffset = (int) (((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);

    if (newImage.Pixels.Length > 0)
    {
        for (int i = 0; i < newImage.Pixels.Length; i++)
        {
            int x = (int) ((i % newImage.PixelWidth) + xoffset);
            int y = (int) ((i / newImage.PixelWidth) + yoffset);
            newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
        }

        using (MemoryStream ms = new MemoryStream())
        {
            newImage.SaveJpeg(ms, (int) newImage.PixelWidth, 
                (int) newImage.PixelHeight, 0, 100);

            image.SetSource(ms);
        }
    }
    else
    {
    }

    ProgressBar pb = new ProgressBar();
    pb.IsEnabled = true;
    LayoutRoot.Children.Add(pb);
    int idReceipt = (int) PhoneApplicationService.Current.State["paragon"];
    await ReceiptsHelper.addPhotosToReceipt(image, idReceipt);
    NavigationService.Navigate(new Uri("/7.0/StronaParagonu.xaml", UriKind.Relative));
}

当我的图像是垂直的时,一切正常,但当我的图像是水平的时,我得到的数据索引超出界限:

newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];

我不确切地知道我做错了什么。

有人可以帮忙吗?

编辑: 我将代码更改为:

            if (wb.PixelWidth > wb.PixelHeight)
            {
                for (int i = 0; i < newImage.Pixels.Length; i++)
                {
                    int x = (int)((i % newImage.PixelWidth) + xoffset);
                    int y = (int)((i / newImage.PixelWidth) + yoffset);
                     newImage.Pixels[i] = wb.Pixels[x * wb.PixelHeight + y];
                }
            }
            else
            {
                for (int i = 0; i < newImage.Pixels.Length; i++)
                {
                    int x = (int)((i % newImage.PixelWidth) + xoffset);
                    int y = (int)((i / newImage.PixelWidth) + yoffset);
                    newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
                }
            }

结果我有this

之类的东西

也许有一些解决方法,我可以将图像翻转90度? 我尝试过WriteableBitmapEx但它不起作用。

1 个答案:

答案 0 :(得分:0)

我看到的第一件事是:

int yoffset = (int) (((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);

我想应该有Point2.Y

第二件事是@Rashed在评论中提到的:

  

如果要获得水平图像,则必须更改X和Y位置:newImage.Pixels[i] = wb.Pixels[x * wb.PixelHeight + y];

但是请注意我真的在这里猜测,因为它已经很晚了,我看不清楚; - )