C #: GDI + Обрезка изображений - PullRequest
1 голос
/ 23 июня 2009

У меня есть изображение. Я хочу обрезать 10 пикселей слева и 10 пикселей справа от изображения. Для этого я использовал приведенный ниже код

    string oldImagePath="D:\\RD\\dotnet\\Images\\photo1.jpg";
    Bitmap myOriginalImage = (Bitmap)Bitmap.FromFile(oldImagePath);
    int newWidth = myOriginalImage.Width;
    int newHeight = myOriginalImage.Height;
    Rectangle cropArea = new Rectangle(10,0, newWidth-10, newHeight);

    Bitmap target = new Bitmap(cropArea.Width, cropArea.Height);
    using (Graphics g = Graphics.FromImage(target))
    {
        g.DrawImage(myOriginalImage,cropArea);
    }

    target.Save("D:\\RD\\dotnet\\Images\\test.jpg");

Но это не дает мне результатов, которых я ожидаю. Это приводит к выводу изображения, которое имеет 10 px обрезанного справа и измененного размера изображения. Вместо обрезки я изменяю ширину, я думаю. Так что изображение сжимается (по ширине). Кто-нибудь может меня поправить? Заранее спасибо

Ответы [ 5 ]

2 голосов
/ 23 июня 2009

Ваша новая ширина должна быть уменьшена вдвое, так как вы будете обрезать это количество с обеих сторон.

Далее, когда рисуете изображение в новом, нарисуйте его с отрицательным смещением. Это приводит к тому, что область, которая вас не интересует, обрезается.

int cropX = 10;
Bitmap target = new Bitmap(myOriginalImage.Width - 2*cropX, myOriginalImage.Height);
using (Graphics g = Graphics.FromImage(target))
{
    g.DrawImage(myOriginalImage, -cropX, 0);
}
0 голосов
/ 21 ноября 2009

Вам нужно использовать перегрузку, в которой вы указываете и прямоугольник назначения, и прямоугольник источника.

Ниже приведена интерактивная форма этого с использованием графического блока на форме. Это позволяет перетаскивать изображение вокруг. Я предлагаю сделать окно с картинками размером 100 x 100 и иметь намного большее изображение, например полноэкранное окно, которое вы сняли с помощью alt-prtscr.

class Form1 : Form
{
    // ...
    Image i = new Bitmap(@"C:\Users\jasond\Pictures\foo.bmp");
    Point lastLocation = Point.Empty;
    Size delta = Size.Empty;
    Point drawLocation = Point.Empty;
    bool dragging = false;
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            if (!dragging)
            {
                lastLocation = e.Location;
                dragging = true;
            }
            delta = new Size(lastLocation.X - e.Location.X, lastLocation.Y - e.Location.Y);
            lastLocation = e.Location;
            if (!delta.IsEmpty)
            {
                drawLocation.X += delta.Width;
                drawLocation.Y += delta.Height;
                pictureBox1.Invalidate();
            }
        }
        else
        {
            dragging = false;
        }
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Rectangle source = new Rectangle(drawLocation,pictureBox1.ClientRectangle.Size);
        e.Graphics.DrawImage(i,pictureBox1.ClientRectangle,source, GraphicsUnit.Pixel);
    }
    //...
0 голосов
/ 23 июня 2009

Кори Росс прав. Кроме того, вы можете перевести вдоль отрицательной оси х и рендеринга в 0,0, 0,0. Должны давать идентичные результаты.

using (Graphics g = Graphics.FromImage(target))
{
    g.TranslateTransform(-cropX, 0.0f);
    g.DrawImage(myOriginalImage, 0.0f, 0.0f);
}
0 голосов
/ 23 июня 2009

Я думаю, эта строка

Rectangle cropArea = new Rectangle(10,0, newWidth-10, newHeight);

должно быть

Rectangle cropArea = new Rectangle(10,0, newWidth-20, newHeight);

Установите ширину нового прямоугольника на 20 меньше, чем оригинал - 10 для каждой стороны.

Некоторая информация о том, какой результат он дает, будет полезна для подтверждения этого.

0 голосов
/ 23 июня 2009

Хорошо, я совершенно не могу объяснить это, но подождите:

Функция DrawImage требует местоположения изображения, а также его положения. Вам нужна вторая позиция для обрезки, как то, как старое относится к новому, а не наоборот.

Это было совершенно непонятно, но вот код.

g.DrawImage(myOriginalImage, -cropArea.X, -cropArea.Y);

Надеюсь, это объясняет это больше, чем я.

...