Member 1102212 Ответов: 1

Создание небольшого растрового изображения как части существующего


Я пытаюсь создать и показать часть существующего растрового изображения. При щелчке мыши над полем изображения отображается небольшой прямоугольник, который копируется в новое растровое изображение. Проблема в том, что новое растровое изображение имеет непредсказуемое смещение и не показывает точно содержимое прямоугольника. Я предполагаю, что проблема заключается в том, что я использую GraphicsUnit.Point вместо пиксельного формата, но при попытке использовать пиксельный формат я вижу только белый прямоугольник вместо изображения.



//Нажмите на picturebox исходного изображения
частная pictureBox1_Click недействительным(объект отправителя, EventArgs в электронной)
{
int x = ((MouseEventArgs)e).X;
int y = ((MouseEventArgs)e).Y;

m_Rectangle = новый прямоугольник(x, y, 20, 20);
имя picturebox1.Обновить();
m_Bitmap = CopyToBitmap();
}

//Отображение красного прямоугольника после щелчка пользователя
private void pictureBox1_Paint(отправитель объекта, PaintEventArgs e)
{
если (m_Rectangle != нуль)
{
ВАР г = е.Графика;
г. Объекта Drawrectangle(Ручки.Красный, m_Rectangle);

}
}

частное растровое изображение CopyToBitmap()
{

Источник растрового изображения = (Bitmap)pictureBox1.Image;

Прямоугольное сечение = новый прямоугольник(новая точка(m_Rectangle.Местоположение.Х ,m_Rectangle.Местоположение.Y), новый размер(20, 20));

Bitmap bmp = новое растровое изображение( раздел.Ширина, сечение.Высота, Пиксельформат.Format32bppArgb);


использование (графика g = графика.FromImage(bmp))
{
г. Функция drawImage(источник, раздел, m_Rectangle,GraphicsUnit.Точка);
}
//picLetter = поле изображения назначения

пиклеттер.Изображение = bmp;
пиклеттер.Освежить();
возвращение БМП;

}

Что я уже пробовал:

Я использую C# WinForms, .Net Framework 3.5. смещение позиции X не существует, и picturebox не показывает точно содержимое красного прямоугольника

1 Ответов

Рейтинг:
4

OriginalGriff

Проблема именно в этом: точки-это не пиксели.
Ваш прямоугольник измеряется в пикселях - потому что это то, в чем находятся движения мыши.
Но ]ваше изображение рисуется в точках, которые представляют собой систему печати, основанную на том, что одна точка составляет 1/72 дюйма - эти две системы даже немного несовместимы, потому что вы понятия не имеете, каково соотношение между пикселями и точками на вашем конкретном мониторе!

И точечная структура не имеет ничего общего с точечным графическим блоком!

Пока вы не измените изображение на пиксели (или не найдете отображение из координат мыши в точки), этот код не будет работать.

Попробовать это:

private void myPictureBox_Click(object sender, EventArgs e)
    {
    int x = ((MouseEventArgs)e).X;
    int y = ((MouseEventArgs)e).Y;
    Rectangle m_Rectangle = new Rectangle(x, y, 100, 100);
    Bitmap source = (Bitmap)myPictureBox.Image;
    Rectangle section = new Rectangle(new Point(x, y), new Size(100, 100));
    Bitmap bmp = new Bitmap(section.Width, section.Height, PixelFormat.Format32bppArgb);
    using (Graphics g = Graphics.FromImage(bmp))
        {
        g.DrawImage(source, new Rectangle(0, 0, pbShowSection.Width, pbShowSection.Height), m_Rectangle, GraphicsUnit.Pixel);
        }
    pbShowSection.Image = bmp;
    }


Member 1102212

Спасибо за ваш ответ. К сожалению, после изменения графического блока на пиксель вместо картинки отображается белый прямоугольник (без границ). Я использую файл jpeg в качестве источника.

OriginalGriff

Не имеет значения, как и я (исходное изображение преобразуется в растровое изображение внутренне, когда вы его загружаете).
Поэтому загрузите изображение, с которым легко работать, и посмотрите, какую именно часть изображения вы обрезаете. Сделайте размер выделения больше, чтобы вы могли видеть его больше, а затем уменьшите его, когда он будет работать.

Member 1102212

еще раз спасибо за ваш ответ, но обрезанное изображение вообще не отображается после изменения GraphicsUnit, несмотря на то, что задний цвет целевого picturebox прозрачен.

OriginalGriff

Как я уже сказал, начните с "простого" изображения: попробуйте один точно такого же размера, как Picturebox, и который содержит "отчетливое" изображение, чтобы вы могли точно определить, откуда взялась любая часть.

На первый взгляд, ваше изображение намного больше или меньше, чем поле изображения, поэтому оно масштабируется по размеру - но раздел, который вы копируете из него, будет исходить из немасштабированного изображения, поэтому вам нужно установить, что код работает, прежде чем вы начнете возиться с такими сложностями, как масштабированные дисплеи. Но мы не можем видеть ваш экран, а тем более ваш код, поэтому мы не можем сказать эти вещи!

Member 1102212

Я только что понял, что мне нужно преобразовать координаты точек сечения в пиксельные координаты:
private int PointToPixelX(int pointX)
{
десятой доли процента = (десятичное число) pointX / (десятичное)имя picturebox1.Ширина;
Источник растрового изображения = (Bitmap)pictureBox1.Image;
вернуть обменять.ToInt32(источник.Ширина * процент);
}

private int PointToPixelY(int pointY)
{
десятой доли процента = (десятичное число)острые / (десятичное) имя picturebox1.Высота;
Источник растрового изображения = (Bitmap)pictureBox1.Image;
вернуть обменять.ToInt32(источник.Высота * процент);
}
Теперь он работает нормально, спасибо за вашу помощь

OriginalGriff

Всегда пожалуйста!