Untitled
unknown
plain_text
3 years ago
18 kB
9
Indexable
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class LiveImageProcessing
{
private PictureBox canvas;
private List<Layer> layers;
private int currentLayerIndex;
private Bitmap outputImage;
private Graphics graphics;
private List<HistoryEntry> history;
private int maxHistory;
// Magic Wand Tool fields
private int magicWandThreshold;
private bool[,] magicWandVisitedPixels;
private Queue<Point> magicWandPixelQueue;
// Polygon Lasso Tool fields
private Point[] polygonPoints;
public LiveImageProcessing(PictureBox canvas)
{
this.canvas = canvas;
layers = new List<Layer>();
currentLayerIndex = -1;
outputImage = new Bitmap(canvas.Width, canvas.Height);
graphics = Graphics.FromImage(outputImage);
history = new List<HistoryEntry>();
maxHistory = 10;
magicWandThreshold = 30;
magicWandVisitedPixels = new bool[outputImage.Width, outputImage.Height];
magicWandPixelQueue = new Queue<Point>();
polygonPoints = new Point[0];
}
public void NewLayer()
{
Bitmap bitmap = new Bitmap(canvas.Width, canvas.Height);
Layer layer = new Layer(bitmap.Width, bitmap.Height);
layer.Bitmap = bitmap;
graphics = Graphics.FromImage(layer.Bitmap);
graphics.Clear(Color.Transparent);
layers.Add(layer);
currentLayerIndex = layers.Count - 1;
UpdateOutputImage();
}
public void SelectLayer(int index)
{
if (index >= 0 && index < layers.Count)
{
currentLayerIndex = index;
UpdateOutputImage();
}
}
public void DeleteLayer()
{
if (layers.Count > 1 && currentLayerIndex >= 0)
{
layers.RemoveAt(currentLayerIndex);
currentLayerIndex = 0;
UpdateOutputImage();
}
}
public void MoveLayerUp()
{
if (currentLayerIndex > 0)
{
Layer layer = layers[currentLayerIndex];
layers.RemoveAt(currentLayerIndex);
layers.Insert(currentLayerIndex - 1, layer);
currentLayerIndex--;
UpdateOutputImage();
}
}
public void MoveLayerDown()
{
if (currentLayerIndex < layers.Count - 1)
{
Layer layer = layers[currentLayerIndex];
layers.RemoveAt(currentLayerIndex);
layers.Insert(currentLayerIndex + 1, layer);
currentLayerIndex++;
UpdateOutputImage();
}
}
public void DrawLine(Point startPoint, Point endPoint, Color color, int size)
{
AddHistoryEntry();
graphics.DrawLine(new Pen(color, size), startPoint, endPoint);
UpdateOutputImage();
}
public void DrawRectangle(Rectangle rectangle, Color color, int size)
{
AddHistoryEntry();
graphics.DrawRectangle(new Pen(color, size), rectangle);
UpdateOutputImage();
}
public void FillRectangle(Rectangle rectangle, Color color)
{
AddHistoryEntry();
graphics.FillRectangle(new SolidBrush(color), rectangle);
UpdateOutputImage();
}
public void DrawEllipse(Rectangle rectangle, Color color, int size)
{
AddHistoryEntry();
graphics.DrawEllipse(new Pen(color, size), rectangle);
UpdateOutputImage();
}
public void FillEllipse(Rectangle rectangle, Color color)
{
AddHistoryEntry();
graphics.FillEllipse(new SolidBrush(color), rectangle);
UpdateOutputImage();
}
public void DrawPolygon(Point[] points, Color color, int size)
{
AddHistoryEntry();
graphics.DrawPolygon(new Pen(color, size), points);
UpdateOutputImage();
}
public void FillPolygon(Point[] points, Color color)
{
AddHistoryEntry();
graphics.FillPolygon(new SolidBrush(color), points);
UpdateOutputImage();
}
public void DrawCurve(Point[] points, Color color, int size)
{
AddHistoryEntry();
graphics.DrawCurve(new Pen(color, size), points);
UpdateOutputImage();
}
public void DrawBezier(Point startPoint, Point controlPoint1, Point controlPoint2, Point endPoint, Color color, int size)
{
AddHistoryEntry();
graphics.DrawBezier(new Pen(color, size), startPoint, controlPoint1, controlPoint2, endPoint);
UpdateOutputImage();
}
public void FillRegion(Region region, Color color)
{
AddHistoryEntry();
graphics.FillRegion(new SolidBrush(color), region);
UpdateOutputImage();
}
public void DrawImage(Bitmap image, Rectangle rectangle)
{
AddHistoryEntry();
graphics.DrawImage(image, rectangle);
UpdateOutputImage();
}
public void ResizeImage(int width, int height)
{
AddHistoryEntry();
Bitmap newImage = new Bitmap(outputImage, width, height);
outputImage = newImage;
canvas.Image = outputImage;
}
public void RotateImage(float angle)
{
AddHistoryEntry();
Bitmap rotatedImage = new Bitmap(outputImage.Width, outputImage.Height);
Graphics g = Graphics.FromImage(rotatedImage);
g.TranslateTransform((float)outputImage.Width / 2, (float)outputImage.Height / 2);
g.RotateTransform(angle);
g.TranslateTransform(-(float)outputImage.Width / 2, -(float)outputImage.Height / 2);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(outputImage, 0, 0);
g.Dispose();
outputImage = rotatedImage;
canvas.Image = outputImage;
}
public void FlipImage(bool horizontal)
{
AddHistoryEntry();
Bitmap flippedImage = new Bitmap(outputImage.Width, outputImage.Height);
Graphics g = Graphics.FromImage(flippedImage);
if (horizontal)
{
g.ScaleTransform(-1, 1);
g.TranslateTransform(-outputImage.Width, 0);
}
else
{
g.ScaleTransform(1, -1);
g.TranslateTransform(0, -outputImage.Height);
}
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(outputImage, 0, 0);
g.Dispose();
outputImage = flippedImage;
canvas.Image = outputImage;
}
public void BrightnessCorrection(int amount)
{
AddHistoryEntry();
Bitmap adjustedImage = new Bitmap(outputImage.Width, outputImage.Height);
for (int x = 0; x < outputImage.Width; x++)
{
for (int y = 0; y < outputImage.Height; y++)
{
Color originalColor = outputImage.GetPixel(x, y);
int r = originalColor.R + amount;
int g = originalColor.G + amount;
int b = originalColor.B + amount;
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
Color adjustedColor = Color.FromArgb(originalColor.A, r, g, b);
adjustedImage.SetPixel(x, y, adjustedColor);
}
}
outputImage = adjustedImage;
canvas.Image = outputImage;
}
public void ContrastCorrection(double amount)
{
AddHistoryEntry();
Bitmap adjustedImage = new Bitmap(outputImage.Width, outputImage.Height);
for (int x = 0; x < outputImage.Width; x++)
{
for (int y = 0; y < outputImage.Height; y++)
{
Color originalColor = outputImage.GetPixel(x, y);
int r = (int)(amount * (originalColor.R - 128) + 128);
int g = (int)(amount * (originalColor.G - 128) + 128);
int b = (int)(amount * (originalColor.B - 128) + 128);
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
Color adjustedColor = Color.FromArgb(originalColor.A, r, g, b);
adjustedImage.SetPixel(x, y, adjustedColor);
}
}
outputImage = adjustedImage;
canvas.Image = outputImage;
}
public void SaturationCorrection(double amount)
{
AddHistoryEntry();
Bitmap adjustedImage = new Bitmap(outputImage.Width, outputImage.Height);
for (int x = 0; x < outputImage.Width; x++)
{
for (int y = 0; y < outputImage.Height; y++)
{
Color originalColor = outputImage.GetPixel(x, y);
double r = originalColor.R / 255.0;
double g = originalColor.G / 255.0;
double b = originalColor.B / 255.0;
double max = Math.Max(r, Math.Max(g, b));
double min = Math.Min(r, Math.Min(g, b));
double l = (max + min) / 2;
double s;
if (max == min)
{
s = 0;
}
else
{
s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min);
}
double newS = s * amount;
if (newS > 1) newS = 1;
if (newS < 0) newS = 0;
double newL = l;
if (newS != 0)
{
if (newL < 0.5) newL *= (1 + newS);
else newL = newL * (1 - newS) + newS;
}
int newR = (int)(newL * 2.55 * (r / (max * 255)) + 0.5);
int newG = (int)(newL * 2.55 * (g / (max * 255)) + 0.5);
int newB = (int)(newL * 2.55 * (b / (max * 255)) + 0.5);
if (newR > 255) newR = 255;
if (newG > 255) newG = 255;
if (newB > 255) newB = 255;
if (newR < 0) newR = 0;
if (newG < 0) newG = 0;
if (newB < 0) newB = 0;
Color adjustedColor = Color.FromArgb(originalColor.A, newR, newG, newB);
adjustedImage.SetPixel(x, y, adjustedColor);
}
}
outputImage = adjustedImage;
canvas.Image = outputImage;
}
public void ContentAwareFill(Rectangle source, Point destination)
{
AddHistoryEntry();
int x = destination.X;
int y = destination.Y;
int w = source.Width;
int h = source.Height;
Bitmap sourceImage = outputImage.Clone(source, outputImage.PixelFormat);
Bitmap destinationImage = new Bitmap(outputImage.Width, outputImage.Height);
Graphics g = Graphics.FromImage(destinationImage);
g.DrawImage(outputImage, 0, 0);
g.Dispose();
BitmapData sourceData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData destinationData = destinationImage.LockBits(new Rectangle(0, 0, destinationImage.Width, destinationImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
int sourceStride = sourceData.Stride;
int destinationStride = destinationData.Stride;
byte[] sourcePixels = new byte[sourceStride * h];
byte[] destinationPixels = new byte[destinationStride * destinationImage.Height];
Marshal.Copy(sourceData.Scan0, sourcePixels, 0, sourcePixels.Length);
Marshal.Copy(destinationData.Scan0, destinationPixels, 0, destinationPixels.Length);
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
int sourceIndex = i * sourceStride + j * 4;
int destinationIndex = (y + i) * destinationStride + (x + j) * 4;
destinationPixels[destinationIndex] = sourcePixels[sourceIndex];
destinationPixels[destinationIndex + 1] = sourcePixels[sourceIndex + 1];
destinationPixels[destinationIndex + 2] = sourcePixels[sourceIndex + 2];
destinationPixels[destinationIndex + 3] = sourcePixels[sourceIndex + 3];
}
}
Marshal.Copy(destinationPixels, 0, destinationData.Scan0, destinationPixels.Length);
sourceImage.UnlockBits(sourceData);
destinationImage.UnlockBits(destinationData);
outputImage = destinationImage;
canvas.Image = outputImage;
}
public void AddLayer()
{
AddHistoryEntry();
layers.Add(new Layer(outputImage));
}
public void SetActiveLayer(int layerIndex)
{
if (layerIndex >= 0 && layerIndex < layers.Count)
{
activeLayerIndex = layerIndex;
outputImage = layers[layerIndex].GetImage();
canvas.Image = outputImage;
}
}
public void MergeLayers()
{
AddHistoryEntry();
Bitmap mergedImage = new Bitmap(outputImage.Width, outputImage.Height);
Graphics g = Graphics.FromImage(mergedImage);
for (int i = 0; i < layers.Count; i++)
{
Bitmap layerImage = layers[i].GetImage();
g.DrawImage(layerImage, 0, 0);
}
g.Dispose();
layers.Clear();
layers.Add(new Layer(mergedImage));
activeLayerIndex = 0;
outputImage = mergedImage;
canvas.Image = outputImage;
}
public void AddLayerMask(Rectangle selection)
{
if (activeLayerIndex >= 0 && activeLayerIndex < layers.Count)
{
AddHistoryEntry();
LayerMask layerMask = new LayerMask(selection, outputImage.Width, outputImage.Height);
layers[activeLayerIndex].SetMask(layerMask);
layerMaskedImage = layerMask.ApplyMask(outputImage);
canvas.Image = layerMaskedImage;
}
}
public void SetLayerMask(Rectangle selection)
{
if (activeLayerIndex >= 0 && activeLayerIndex < layers.Count)
{
AddHistoryEntry();
layers[activeLayerIndex].GetMask().SetMask(selection, outputImage.Width, outputImage.Height);
layerMaskedImage = layers[activeLayerIndex].GetMask().ApplyMask(outputImage);
canvas.Image = layerMaskedImage;
}
}
public void RemoveLayerMask()
{
if (activeLayerIndex >= 0 && activeLayerIndex < layers.Count)
{
AddHistoryEntry();
layers[activeLayerIndex].SetMask(null);
layerMaskedImage = null;
canvas.Image = outputImage;
}
}
public void ApplyLayerMask()
{
if (activeLayerIndex >= 0 && activeLayerIndex < layers.Count && layerMaskedImage != null)
{
AddHistoryEntry();
layers[activeLayerIndex].SetImage(layerMaskedImage);
outputImage = layerMaskedImage;
layerMaskedImage = null;
canvas.Image = outputImage;
}
}
public void Undo()
{
if (historyIndex > 0)
{
historyIndex--;
outputImage = new Bitmap(history[historyIndex]);
canvas.Image = outputImage;
}
}
public void Redo()
{
if (historyIndex < history.Count - 1)
{
historyIndex++;
outputImage = new Bitmap(history[historyIndex]);
canvas.Image = outputImage;
}
else
{
throw new NotImplementedException();
}
}
}
public class Layer
{
private Bitmap image;
private LayerMask mask;
public Layer(Bitmap image)
{
this.image = image;
}
public Bitmap GetImage()
{
return image;
}
public void SetImage(Bitmap image)
{
this.image = image;
}
public LayerMask GetMask()
{
return mask;
}
public void SetMask(LayerMask mask)
{
this.mask = mask;
}
}
public class LayerMask
{
private Rectangle selection;
private byte[] mask;
private int width;
private int height;
public LayerMask(Rectangle selection, int width, int height)
{
this.selection = selection;
mask = new byte[width * height];
this.width = width;
this.height = height;
}
public Rectangle GetSelection()
{
return selection;
}
public void SetSelection(Rectangle selection)
{
this.selection = selection;
}
public byte[] GetMask()
{
return mask;
}
public void SetMask(byte[] mask)
{
this.mask = mask;
}
public void SetMask(Rectangle selection, int width, int height)
{
this.selection = selection;
mask = new byte[width * height];
}
public void SetMaskPixel(int x, int y, byte value)
{
mask[y * width + x] = value;
}
public byte GetMaskPixel(int x, int y)
{
return mask[y * width + x];
}
public Bitmap ApplyMask(Bitmap image)
{
Bitmap maskedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color originalColor = image.GetPixel(x, y);
byte maskValue = mask[y * width + x];
Color newColor = Color.FromArgb(originalColor.A, originalColor.R, originalColor.G, originalColor.B);
if (maskValue == 0)
{
newColor = Color.FromArgb(0, 0, 0, 0);
}
maskedImage.SetPixel(x, y, newColor);
}
}
return maskedImage;
}
}Editor is loading...