Обрезка и печать изображений без искажений в С#
Я использую WinForms. В моей форме у меня есть картинка, которую я использую для отображения документов изображений. Проблема заключается в том, когда я обрезаю изображение, а затем распечатываю документ, изображение слегка искажается. Если я не обрезаю документ изображения и не печатаю его регулярно, документ изображения не будет искажен.
Как обрезать и распечатывать документы изображений без их искажения?
Или есть лучший способ закодировать это, чтобы он мог обрезать и печатать без искажения документа изображения? Если да, то как я могу это сделать?
Примечания:
-
У моего Picturebox установлен Zoom, потому что изображения, с которыми я работаю, большие:
-
Пример документа изображения Размеры: 2500 x 3100
-
У моего фотобумага нет рамки
int _cropX, _cropY, _cropWidth, _cropHeight;
public Pen _cropPen;
private State _currentState;
private enum State
{
Crop
}
private void Open_btn_Click(object sender, EventArgs e)
{
// open file dialog
OpenFileDialog open = new OpenFileDialog();
if (open.ShowDialog() == DialogResult.OK)
{
// display image in picture box
pictureBox1.Image = new Bitmap(open.FileName);
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
try
{
if (Crop_Checkbox.Checked == true)
{
Cursor = Cursors.Default;
if (_currentState == State.Crop)
{
if (_cropWidth < 1)
{
return;
}
Rectangle rect = new Rectangle(_cropX, _cropY, _cropWidth, _cropHeight);
//First we define a rectangle with the help of already calculated points
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
//Original image
Bitmap img = new Bitmap(_cropWidth, _cropHeight);
// for cropinf image
Graphics g = Graphics.FromImage(img);
// create graphics
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//set image attributes
g.DrawImage(originalImage, 0, 0, rect, GraphicsUnit.Pixel);
pictureBox1.Image = img;
pictureBox1.Width = img.Width;
pictureBox1.Height = img.Height;
}
}
else
{
Cursor = Cursors.Default;
}
}
catch (Exception)
{
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (Crop_Checkbox.Checked == true)
{
if (_currentState == State.Crop)
{
Cursor = Cursors.Cross;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
//X and Y are the coordinates of Crop
pictureBox1.Refresh();
_cropWidth = e.X - _cropX;
_cropHeight = e.Y - _cropY;
pictureBox1.CreateGraphics().DrawRectangle(_cropPen, _cropX, _cropY, _cropWidth, _cropHeight);
}
}
}
else
{
Cursor = Cursors.Default;
}
}
private void Crop_Checkbox_CheckedChanged(object sender, EventArgs e)
{
if (Crop_Checkbox.Checked == true)
{
this.Cursor = Cursors.Cross;
}
}
private void Print_btn_Click(object sender, EventArgs e)
{
System.Drawing.Printing.PrintDocument myPrintDocument1 = new System.Drawing.Printing.PrintDocument();
PrintDialog myPrinDialog1 = new PrintDialog();
myPrintDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
myPrinDialog1.Document = myPrintDocument1;
if (myPrinDialog1.ShowDialog() == DialogResult.OK)
{
myPrintDocument1.Print();
}
}
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawImage(pictureBox1.Image, 10, 10); //(Standard paper size is 850 x 1100 or 2550 x 3300 pixels)
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (Crop_Checkbox.Checked == true)
{
if (_currentState == State.Crop)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Cursor = Cursors.Cross;
_cropX = e.X;
_cropY = e.Y;
_cropPen = new Pen(Color.FromArgb(153, 180, 209), 3); //2 is Thickness of line
_cropPen.DashStyle = DashStyle.DashDotDot;
pictureBox1.Refresh();
}
}
}
else
{
Cursor = Cursors.Default;
}
}
![введите описание изображения здесь]()
Тест: Слегка искаженный:
![введите описание изображения здесь]()
Тест: Не искажен:
![введите описание изображения здесь]()
![введите описание изображения здесь]()
Тест:
На рисунке выше приведен тест. Это то, что произошло, когда я взял приведенный ниже код из pictureBox1_MouseUp:
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
И отредактировано/заменено (originalImage to pictureBox1.Image):
g.DrawImage(pictureBox1.Image, 0, 0, rect, GraphicsUnit.Pixel);
Ответы
Ответ 1
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
Скорее всего, там, где проблема началась. Это может привести к тому, что pictureBox1.Image будет перемасштабирован, чтобы приспособить его к размеру pictureBox1. Зависит от того, имеют ли рамки изображения границы и значение свойства SizeMode. Повторное масштабирование приводит к повторной выборке изображения, цвет пикселя в новом растровом изображении вычисляется из значений соседних пикселей исходного изображения в соответствии с выбранным интерполяционным модулем.
Это фактически размывает полученное изображение. Это хорошо работает на фотографии, но это текст, который критически зависит от пикселей сглаживания, чтобы выглядеть прилично на мониторе с низким разрешением. Небольшие изменения этих пикселей разрушают эффект, и они больше не плавно смешивают форму буквы с фоном. Они становятся более заметными, лучший способ описать, что полученный текст выглядит "жирным".
Я не вижу очевидной причины делать это вообще в опубликованном коде. Удалите инструкцию и замените originalImage на pictureBox1.Image
.
Также будьте осторожны, что печать этого изображения может быть разочаровывающей. Теперь эти пиксели сглаживания превращаются в 6x6 капель чернил на бумаге. Это всегда выглядит хорошо, когда у тебя длинные руки. Пока размер шрифта такой маленький, и у вас нет контроля над выбором сглаживания, тогда вы можете сделать это очень мало. Печатный текст только когда-либо выглядит хорошо, когда вы используете PrintDocument и Graphics.DrawString().