Как я могу получить цвет фона изображения, даже если на изображении больше цветов?C#

Место общения программистов C#
Ответить
Anonymous
 Как я могу получить цвет фона изображения, даже если на изображении больше цветов?

Сообщение Anonymous »


Фон изображения в этом случае белый, но есть и синие цвета и, возможно, даже больше цветов, но если я перемещаю мышь на белых областях, он всегда получает RGB 255,255,2555555555555551111 раза. что, когда я использую мышь для рисования прямоугольника, где я хочу заменить/добавить текст, который не только белый. белый. Если я нарисую прямоугольник на белой области только на изображении, он поместит там белый цвет, и он будет выглядеть хорошо. /> Есть ли способ найти или сделать цвет фона, чтобы быть похожим на цвет фона изображения, даже если я нарисовал прямоугольник по областям с другими цветами? < /p>
Полный код. Это немного длинное, но все, что там связано, поэтому я не уверен, какие части только показывать: < /p>
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace ImageTextReplacer
{
public partial class Form1 : Form
{
private Bitmap? originalImage;
private Rectangle selectionRect;
private bool isSelecting = false;
private Point startPoint;
private StreamWriter? colorLoggerFile;

public Form1()
{
InitializeComponent();
}

private void btnLoadImage_Click(object sender, EventArgs e)
{
using (OpenFileDialog dlg = new OpenFileDialog())
{
dlg.Title = "Open Image";
dlg.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp";

if (dlg.ShowDialog() == DialogResult.OK)
{
originalImage = new Bitmap(dlg.FileName);
pictureBox.Image = new Bitmap(originalImage);
}
}
}

private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (pictureBox.Image == null) return;

isSelecting = true;
startPoint = e.Location;
selectionRect = new Rectangle(e.Location, new Size(0, 0));
pictureBox.Invalidate();
}

private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (isSelecting)
{
int x = Math.Min(e.X, startPoint.X);
int y = Math.Min(e.Y, startPoint.Y);
int width = Math.Abs(e.X - startPoint.X);
int height = Math.Abs(e.Y - startPoint.Y);
selectionRect = new Rectangle(x, y, width, height);
pictureBox.Invalidate();
}

if(originalImage == null) return;
{
GetColorsMouseMove(e, originalImage);
}
}

private void GetColorsMouseMove(MouseEventArgs e, Bitmap originalBitmap)
{
if (originalBitmap == null) return;

float scale = Math.Min((float)pictureBox.Width / originalBitmap.Width,
(float)pictureBox.Height / originalBitmap.Height);
int offsetX = (int)((pictureBox.Width - originalBitmap.Width * scale) / 2);
int offsetY = (int)((pictureBox.Height - originalBitmap.Height * scale) / 2);

int imgX = (int)((e.X - offsetX) / scale);
int imgY = (int)((e.Y - offsetY) / scale);

if (imgX < 0 || imgY < 0 || imgX >= originalBitmap.Width || imgY >= originalBitmap.Height) return;

Color pixel = originalBitmap.GetPixel(imgX, imgY);

string line = $"X={imgX}, Y={imgY}, Color={pixel.Name}, R={pixel.R}, G={pixel.G}, B={pixel.B}";
textBoxColor.Text = line;
Console.WriteLine(line); // for debug output

try
{
colorLoggerFile ??= new StreamWriter("color_scan_log.txt", append: true);
colorLoggerFile.WriteLine(line);
colorLoggerFile.Flush();
}
catch { }
}

private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
isSelecting = false;
pictureBox.Invalidate();
}

private void pictureBox_Paint(object sender, PaintEventArgs e)
{
if (selectionRect != Rectangle.Empty && selectionRect.Width > 0 && selectionRect.Height > 0)
{
using (Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, selectionRect);
}
}
}

private void btnReplaceText_Click(object sender, EventArgs e)
{
if (originalImage == null || selectionRect.Width == 0 || selectionRect.Height == 0)
{
MessageBox.Show("Please load image and select area.");
return;
}

Rectangle imageRect = GetActualImageRectangle();
if (imageRect == Rectangle.Empty) return;

float scaleX = (float)originalImage.Width / imageRect.Width;
float scaleY = (float)originalImage.Height / imageRect.Height;

Rectangle mappedRect = new Rectangle(
(int)((selectionRect.X - imageRect.X) * scaleX),
(int)((selectionRect.Y - imageRect.Y) * scaleY),
(int)(selectionRect.Width * scaleX),
(int)(selectionRect.Height * scaleY)
);

Bitmap edited = new Bitmap(originalImage);

Color backgroundColor = SampleCenterColor(edited, mappedRect);

using (Graphics g = Graphics.FromImage(edited))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;

using (Brush brush = new SolidBrush(backgroundColor))
{
g.FillRectangle(brush, mappedRect);
}

string text = textBoxNewText.Text;
Font bestFont = CalculateBestFitFont(g, text, mappedRect, "Arial");

using (Brush textBrush = new SolidBrush(Color.FromArgb(0,70,140)))
{
StringFormat sf = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};

g.DrawString(text, bestFont, textBrush, mappedRect, sf);
}
}

pictureBox.Image?.Dispose();
pictureBox.Image = new Bitmap(edited);
originalImage?.Dispose();
originalImage = new Bitmap(edited);
selectionRect = Rectangle.Empty;
pictureBox.Invalidate();
}

private Font CalculateBestFitFont(Graphics g, string text, Rectangle rect, string fontName)
{
float fontSize = 300; // Start large
Font font = new Font(fontName, fontSize, FontStyle.Bold);
SizeF textSize = g.MeasureString(text, font);
const float tolerance = 0.95f; // To leave padding

while ((textSize.Width > rect.Width * tolerance || textSize.Height > rect.Height * tolerance) && fontSize > 1)
{
fontSize -= 1f;
font.Dispose();
font = new Font(fontName, fontSize, FontStyle.Bold);
textSize = g.MeasureString(text, font);
}
return font;
}

private Color SampleCenterColor(Bitmap bmp, Rectangle rect)
{
int centerX = rect.X + rect.Width / 2;
int centerY = rect.Y + rect.Height / 2;

if (centerX >= bmp.Width) centerX = bmp.Width - 1;
if (centerY >= bmp.Height) centerY = bmp.Height - 1;

return bmp.GetPixel(centerX, centerY);
}

private Rectangle GetActualImageRectangle()
{
if (pictureBox.Image == null || originalImage == null)
return Rectangle.Empty;

float imgAspect = (float)originalImage.Width / originalImage.Height;
float boxAspect = (float)pictureBox.Width / pictureBox.Height;

int width, height, x, y;

if (imgAspect > boxAspect)
{
width = pictureBox.Width;
height = (int)(width / imgAspect);
x = 0;
y = (pictureBox.Height - height) / 2;
}
else
{
height = pictureBox.Height;
width = (int)(height * imgAspect);
x = (pictureBox.Width - width) / 2;
y = 0;
}

return new Rectangle(x, y, width, height);
}

protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);

try
{
colorLoggerFile?.Close();
}
catch
{ /* Ignore errors on close */
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/796 ... -on-the-im
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»