Некорректное отображение изображения в PictureBox

Необходимо разрезать изображение на 9 равных Bitmap'ов, смотрю по отладке, размеры всех 9 Bitmap'ов одинаковые, а в своих PictureBox некоторые отображаются некорректно. Подскажите в чем может быть причина?

Примерно вот так это отображается

Примерно так отображаются у меня части картинки.

private Bitmap GetImageBitmap(Bitmap src, Rectangle rect)
{
    Bitmap Image = new Bitmap(src.Width, src.Height);
 
    Graphics g = Graphics.FromImage(Image);
 
    g.DrawImage(src, 0, 0, rect, GraphicsUnit.Pixel); 
 
    return Image;
} 

private List<Bitmap> SliceImage()
{
    List<Bitmap> slices = new List<Bitmap>();
 
    Image origin = OriginalPB.Image;
    Bitmap src = new Bitmap(origin, OriginalPB.Width, OriginalPB.Height);
    int k = 0;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            Rectangle rect = new Rectangle(i * GbPazzlesBox.Controls[k].Width, j * GbPazzlesBox.Controls[k].Height, GbPazzlesBox.Controls[k].Width, GbPazzlesBox.Controls[k].Height);
 
            slices.Add(GetImageBitmap(src, rect));
            k++;
        }
    }
 
    slices.Add(Properties.Resources._null);
    return slices;
}

Код который я использую для разделения изображения на 9 частей. Как бы я не менял размеры прямоугольника(rect) размер картинок не меняется.


Ответы (1 шт):

Автор решения: Alexander Petrov

У вас в коде много "грязи", мелких ошибок и неточностей.

Например:

Image origin = OriginalPB.Image;
Bitmap src = new Bitmap(origin, OriginalPB.Width, OriginalPB.Height);

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

Bitmap src = new Bitmap(origin, origin.Width, origin.Height);

Вот ещё:

private Bitmap GetImageBitmap(Bitmap src, Rectangle rect)
{
    Bitmap Image = new Bitmap(src.Width, src.Height);

Вы передаёте в метод исходное большое изображение и прямоугольник, который задаёт размер маленького изображения, которое нужно получить. Значит должно быть:

Bitmap Image = new Bitmap(rect.Width, rect.Height);

Вот так вы и просчитались где-то в размерах. Просто внимательно просмотрите свой код на наличие таких ошибок и исправьте их.


Не удержался, набросал пример приложения.
Вообще, всё работает даже так, как написано у вас (но это потому что я не допустил ошибок при проектировании GUI; поэтому лучше изменить, как показал я). Отсюда вывод, что ошибка в размерах сделана где-то раньше, при создании пикчабоксов и прочих контролов.

using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WinForm
{
    public partial class Form1 : Form
    {
        PictureBox OriginalPB;
        Panel GbPuzzlesBox;

        public Form1()
        {
            //InitializeComponent();
            Size = new Size(700, 700);

            var bmp = new Bitmap(SystemIcons.Shield.ToBitmap(), 300, 300);
            OriginalPB = new PictureBox { Parent = this, Image = bmp, SizeMode = PictureBoxSizeMode.AutoSize, BorderStyle = BorderStyle.FixedSingle };

            GbPuzzlesBox = new Panel { Parent = this, BorderStyle = BorderStyle.FixedSingle, Top = OriginalPB.Bottom + 20, Size = new Size(300, 300) };

            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    GbPuzzlesBox.Controls.Add(new PictureBox { Parent = GbPuzzlesBox, Size = new Size(100, 100), Left = i * 100, Top = j * 100, BorderStyle = BorderStyle.FixedSingle });

            var images = SliceImage();

            for (int i = 0; i < images.Count; i++)
                (GbPuzzlesBox.Controls[i] as PictureBox).Image = images[i];
        }
        private Bitmap GetImageBitmap(Bitmap src, Rectangle rect)
        {
            Bitmap image = new Bitmap(src.Width, src.Height);
            //Bitmap image = new Bitmap(rect.Width, rect.Height);

            Graphics g = Graphics.FromImage(image);
            g.DrawImage(src, 0, 0, rect, GraphicsUnit.Pixel);
            return image;
        }
        private List<Bitmap> SliceImage()
        {
            List<Bitmap> slices = new List<Bitmap>();
            Image origin = OriginalPB.Image;

            Bitmap src = new Bitmap(origin, OriginalPB.Width, OriginalPB.Height);
            //Bitmap src = new Bitmap(origin, origin.Width, origin.Height);

            int k = 0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    var control = GbPuzzlesBox.Controls[k];
                    var rect = new Rectangle(i * control.Width, j * control.Height, control.Width, control.Height);

                    slices.Add(GetImageBitmap(src, rect));
                    //slices.Add(src.Clone(rect, src.PixelFormat));
                    k++;
                }
            }

            //slices.Add(Properties.Resources._null);
            return slices;
        }
    }
}

Тут на большом PictureBox выводится оригинальное изображение. Оно делится на мелкие и они выводятся в пиксабоксах, размещённых на панели.

У всех задано BorderStyle = BorderStyle.FixedSingle, чтобы было видно их границы.


Используйте метод Bitmap.Clone для получения части изображения.
Ваш метод GetImageBitmap можно полностью выкинуть, заменив его строкой src.Clone(rect, src.PixelFormat).
Т. е. в метод SliceImage будет: slices.Add(src.Clone(rect, src.PixelFormat));

→ Ссылка