Apply the Zoom in/out to Origin Image in WPF - c#

I created an Image with this code
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = ""; // Default file name
myImage = new Image();
try
{
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
string sUri = #dlg.FileName;
Uri src = new Uri(sUri, UriKind.RelativeOrAbsolute);
BitmapImage bmp = new BitmapImage(src);
myImage.Source = bmp;
myImage.Width = 100;
myImage.Height = 100;
}
}
I can zoom in/out on this image
public void Scale(int i, Point center)
{
Matrix m = myImage.RenderTransform.Value;
if (i > 0)
m.ScaleAtPrepend(1.1, 1.1, center.X, center.Y);
else
m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, center.X, center.Y);
myImage.RenderTransform = new MatrixTransform(m);
}
but when I get the ActualWidth or Width or ActualHeight/Height returns the number 100. this means that these changes not applied to origin image (myImage).
Now How to apply the changes (zoom or any changes) to origin Image?
Tanx all;

Transforms only affect the appearance / layout of the object they are applied to and won't make any changes directly to the source. For this you'll need to resize the image yourself, reading the values of the scaling and applying those to the original width and height.
Take a look at something like AForge.Net which has myriad methods for manipulating images allowing control over the quality of the transformation etc.

Related

bitmap merge different amount of images together every time c#

When i run the program, i get a different amount of images(from 20 all the way up to 2000) and i would like to merge all of these images into one image which would preferably be a square.
This is the code i have for getting the file images(the images are in URL format)
int ximg = 1;
int totalImgs = richTextBox1.Lines.Count();
while (ximg < totalImgs)
{
System.Net.WebRequest request = System.Net.WebRequest.Create(richTextBox1.Lines[ximg]);
System.Net.WebResponse response = request.GetResponse();
System.IO.Stream responseStream =
response.GetResponseStream();
Bitmap image = new Bitmap(responseStream);
List<Image> fileList = new List<Image>();
fileList.Add(image);
ximg++;
}
Also every single image has a title in a different richtextbox which i would like to know if it is possible to add a title under the image (richtextbox1.lines[1] (image) = richtextbox2.lines[1] (title)). Is it possible to add a picture as a background picture when merging(to the square image I want to generate)? Is it possible to add a border on every single image picture and merge them with the border? How can the code calculate when its time to change line and start adding images in the next row?
I've tried this code, but it works only if you know the amount of images you want to merge.
Bitmap bitmap = new Bitmap(image1.Width + image2.Width, Math.Max(image1.Height, image2.Height));
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(image1, 0, 0);
g.DrawImage(image2, image1.Width, 0);
}
bitmap.Save("merged.bmp");
I would do it with photoshop but when there are 2000 images to merge together, I just do not have the time.
Is there any way to accomplish such task? Any references would be appreciated!
I have mentioned it above :) !
This solution will create a mosaic of the images from left to right, top to bottom. It does not do anything to maximize the available space. It also assumes that you have a max width and height for the finished image, since it's not realistic to support an arbitrary size.
// where we store the finished mosaic
var mosaic = new Bitmap(maxWidth, maxHeight);
// track the location where we are drawing each image
var imageCorner = new Point(0,0);
// track the height of the current row
var currentRowHeight = 0;
// track the width and height of the mosaic as it grows.
var mosaicWidth = 0;
var mosaicHeight = 0;
using (var g = Graphics.FromImage(bitmap))
{
var borderPen = new Pen(Brushes.Black) { Width = 2 };
var labelFont = new Font("Arial", 10);
var labelBrush = new SolidBrush(Color.Black);
foreach (var image in imageList)
{
if (imageCorner.X + image.Width > maxWidth)
{
// if adding the image to the current row would make it too wide,
// move to the next row by resetting X to zero and adding the
// height of the tallest image to Y
imageCorner.X = 0;
imageCorner.Y += currentRowHeight;
// since this is a new row, it's current height is zero
currentRowHeight = 0;
}
// if adding this image would put us past the
// height of the image, then we're out of room.
if (imageCorner.Y + image.Height > maxHeight)
{
// this skips images if there's no room for them in
// the mosaic, you may want to do something different
Trace.WriteLine($"Image is {image.Height} pixels tall, but only {maxHeight - mosaicHeight} pixels available.");
continue;
}
// draw the image
g.DrawImage(image, imageCorner);
// draw the border
g.DrawRectangle(borderPen,
imageCorner.X, imageCorner.Y,
image.Width, image.Height)
// draw the label
g.DrawText("Image Label", labelBrush, imageCorner.X, imageCorner.Y)
// now that we've drawn the image, we need to shift to the right
imageCorner.X += image.Width;
// row height is the height of the tallest image so far in this row
currentRowHeight = Math.Max(image.Height, currentRowHeight);
// track the total height of the mosaic
mosaicHeight = imageCorner.Y + currentRowHeight;
// mosaic width is just the widest row in the mosaic
mosaicWidth = Math.Max(imageCorner.X, widthOfWidestRow);
}
}
// trim off the parts of the mosaic we didn't fill
mosaic = mosaic.Clone(new Rectangle(0, 0, mosaicWidth, mosaicHeight);
mosaic.Save("merged.bmp");
If you wanted to minimize wasted space, you could sort your list of images in different ways, or calculate ahead of time what a good width and height for the mosaic would be.

how to have my rectangle always on the middle of the image without knowing the size of the incomming image

Trying to add a watermark image to a png image, i´ve been able to do it, but i want to take out the hardCoded size regulation for the rectangle of the waterMark, and make it always stay in the center of the image. How can i achieve this.
public Form1()
{
InitializeComponent();
picBox.Parent = this;
picBox.Dock = DockStyle.Fill;
picBox.SizeMode = PictureBoxSizeMode.Zoom;
Bitmap Jpg = new Bitmap(#"C:\Users\tferreira\Desktop\213123.PNG");
using (Bitmap Bmp = new Bitmap(#"C:\Users\tferreira\Desktop\logo.png"))
{
using (Bitmap WatermarkBmp = new Bitmap(Bmp, Bmp.Width / 1, Bmp.Height / 1))
{
picBox.Image = WatermarkImage(Jpg, WatermarkBmp, new Point(400, 100), 0.40F);
}
}
}
public Bitmap WatermarkImage(Bitmap ImageToWatermark, Bitmap Watermark, Point WatermarkPosition, float Opacity)
{
using (Graphics G = Graphics.FromImage(ImageToWatermark))
{
using (ImageAttributes IA = new ImageAttributes())
{
ColorMatrix CM = new ColorMatrix();
CM.Matrix33 = Opacity;
IA.SetColorMatrix(CM);
G.DrawImage(Watermark, new Rectangle(WatermarkPosition, Watermark.Size), 0, 0, Watermark.Width, Watermark.Height, GraphicsUnit.Pixel, IA);
}
}
return ImageToWatermark;
}
Right now the images are hardCoded but that will be taken out. If anyone can help me make this watermark allways stay centered i thank you.
I fixed this problem with this nice peace of code.
System.Drawing.Image img = System.Drawing.Image.FromFile(JpgFilePath);
Bitmap jpg = new Bitmap(img);
filePath = JpgFilePath;
int Width = jpg.Width;
int Height = jpg.Height;
jpg.SetResolution(300, 300);
WaterMarked = WatermarkImage(jpg, WaterMarkBit, new Point((Width - WaterMarkBit.Width) / 2, (Height - WaterMarkBit.Height) / 2), 0.4F);
WaterMarked.Save(filePath.Replace(".jpg", "") + ".tif", ImageFormat.Tiff);
filesJpgForTif.Add(JpgFilePath.Replace("jpg", "tif"));
Using the the sizes of the image and sizes of the watermark and divide it by 2 it makes the image always stay centered.

How to crop or resize Image to set aspect ratio in asp.net

I have an image control in my webform. I set its width 100px and height 100px. but if someone upload an image of ratio 100 * 120. I want it crop or resize and set 100 * 100. I tried to set max width but not worked , I tried bitmap method with code
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string filename = FileUpload1.FileName;
string directory = Server.MapPath("~/");
Bitmap originalBMP = new Bitmap(FileUpload1.FileContent);
float origWidth = originalBMP.Width;
float origHeight = originalBMP.Height;
float sngRatio = origWidth / origHeight;
float newWidth = 100;
float newHeight = newWidth / sngRatio;
Bitmap newBMP = new Bitmap(originalBMP,Convert.ToInt32(newWidth),Convert.ToInt32(newHeight));
Graphics oGraphics = Graphics.FromImage(newBMP);
oGraphics.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
oGraphics.InterpolationMode=System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
newBMP.Save(directory + filename);
originalBMP = null;
newBMP = null;
oGraphics = null;
Label1.Text = "File <b style='color: red;'>" + filename + "<</b> uploaded.";
Image1.ImageUrl = #"~/" + filename;
}
else
{
Label1.Text = "No file uploaded!";
}
}
it worked but it save the resized image in directery I want to save original image in directory and display the resize image in image control.
Check out Web Image Resize handler on codeplex : http://webimageresizer.codeplex.com/
It is a custom handler to process images.
Sample urls
Taken from the codeplex project's home page
// Returns the image mapping to /bla.jpg resized to width of 100 pixels preserving aspect relative to height
/ImageHandler.ashx?src=/bla.jpg&width=100
// Returns the image mapping to /bla.jpg resized to height of 100 pixels preserving aspect relative to width
/ImageHandler.ashx?src=/bla.jpg&height=100
// Returns the image mapping to /bla.jpg resized to width 100 pixels and a height of 50 pixels
/ImageHandler.ashx?src=/bla.jpg&width=100&height=50
Another option is to use http://imageresizing.net/
The benefit is that it registers a handler to handle images transparently, meaning, that you only add querystring variables to your original image url to manipulate the image.
Sample urls
/images/bla.jpg?h=100&w=100

boundaries cut the image when rotated

I want to rotate an image in the picture box. Here is my code.
public static Bitmap RotateImage(Image image, PointF offset, float angle)
{
if (image == null)
{
throw new ArgumentNullException("image");
}
var rotatedBmp = new Bitmap(image.Width, image.Height);
rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);
var g = Graphics.FromImage(rotatedBmp);
g.TranslateTransform(offset.X, offset.Y);
g.RotateTransform(angle);
g.TranslateTransform(-offset.X, -offset.Y);
g.DrawImage(image, new PointF(0, 0));
return rotatedBmp;
}
private void button1_Click(object sender, EventArgs e)
{
Image image = new Bitmap(pictureBox1.Image);
pictureBox1.Image = (Bitmap)image.Clone();
var oldImage = pictureBox1.Image;
var p = new Point(image.Width / 2, image.Height);
pictureBox1.Image = null;
pictureBox1.Image = RotateImage(image, p, 1);
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
pictureBox1.Refresh();
if (oldImage != null)
{
oldImage.Dispose();
}
}
private void button2_Click(object sender, EventArgs e)
{
Image image = new Bitmap(pictureBox1.Image);
pictureBox1.Image = (Bitmap)image.Clone();
var oldImage = pictureBox1.Image;
var p = new Point(image.Width / 2, image.Height);
pictureBox1.Image = null;
pictureBox1.Image = RotateImage(image, p, -1);
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
pictureBox1.Refresh();
if (oldImage != null)
{
oldImage.Dispose();
}
}
Now the problem is that when I rotate the image it gets cut. Here is the situation.
I have stretched the picture box and changed the colour of form just for clear picture.
My question is when I have used the statement
pictureBox1.Image = RotateImage(image, p, 1);
Then why is the picture not getting right after postion as this is the same statement used for any situation where we have to assign some image to groupbox. Why is not it working here? I have searched it before but the most of the searches seem irrelevant to me because they use filip function which rotate through 90,180,270. But I want to rotate by some degree maximum upto 10 degree.
Rotating Controls is not something supported by default (links talking about this: link1, link2). The reason why the picture gets cut is because, after the rotation, its width is bigger than the pictureBox1 one; thus a quick solution would be updating its size after the rotation:
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize; //Adapts the size automatically
or
pictureBox1.Width = image.Width;
pictureBox1.Height = image.Height;
This should be an acceptable solution (there has to be enough free space to account for the new dimensions of the image after being rotated anyway). The other option would be affecting the PictureBox control directly (by affecting the rectangle defining its boundaries, for example) what would be much more difficult.
Well i have come to know that win Forms are not meant for any transformations and rotations.Changing the mode to AutoSize does not make a difference. The best thing for rotation and transformation is WPF.
WPF has a good transformation classes which rotate and transform objects without affecting the object. The object does not get blurred.
You can use This for rotations and transformations.

Add extra white space to a scanned image using kofax image controls

What I'm After:
I'm trying to create an extra 1/4 inch of white space to be appended to the TOP of the image during the scanning process.
Using the Kofax Image Controls Toolkit is it possible within one of the following events to add extra white space to the top of the image when scanning?
_PageStart
_PageEnd
_PageAnnotate
_PageDone
Most of the properties available are read only... I know I can set the scan size in the beginning to say 14 inches and when scanning an 11 inch document I will get my extra 3 inches at the bottom of the image. I want to achieve the same principle but at the top of the document and only about a quarter of an inch tall.
So in all the research I did trying to make this possible I came to the conclusion it is in fact not possible...
The only drawbacks about this method were the speed issues after the fact. It did end up slowing down things a good bit.. Hope this helps someone else! Upvote if it helps you please. ;)
What I ended up doing is not using the _PageAnnotate event raised by the Kofax Image Controls and in turn I ended up turning off that event by setting .hDCCreate = false on the Kofax Scan control. Not creating a DC when scanning speeds up the process a little bit not bogging down the processor with all the uncompressing and compressing of the image.
Instead of using the built in Kofax Image Controls event _PageAnnotate I used the _PageDone event and from there used native c# objects/functions to achieve what I was after. Below is the code I ended up with.
if (!Imaging.AnnotateImage(sImageFileName, "This is my annotation..."))
{
Debug.WriteLine("Scan Error! Could not annotate the image.");
}
The code for the class I made called 'Imaging.cs'...
static class Imaging
{
public static bool AnnotateImage(string sFilePath, string sText)
{
try
{
// Get an ImageCodecInfo object that represents the TIFF codec.
ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/tiff");
Encoder myEncoder = Encoder.Compression;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, (long)EncoderValue.CompressionCCITT4);
myEncoderParameters.Param[0] = myEncoderParameter;
//Create some global variables
Point pointPosition = new Point(0, 0);
PointF pPos = new PointF((float)pointPosition.X, (float)pointPosition.Y);
Bitmap newBmp;
Graphics g;
Font fNewFont;
SizeF sizeTextSize;
Rectangle rectTextSize;
//Set inital width and height variables
int iW;
int iH;
int iAnnotationH = 44;
using(Image iSource = Image.FromFile(sFilePath))
{
iW = iSource.Width;
iH = iSource.Height;
//Increase the height of the image
iH += iAnnotationH;
//Create the new bitmap object
newBmp = new Bitmap(iW, iH);
newBmp.SetResolution(200.0F, 200.0F);
g = Graphics.FromImage(newBmp);
g.Clear(Color.White);
g.DrawImageUnscaled(iSource, 0, iAnnotationH, iW, iH);
//Create the font object to draw the annotation text
fNewFont = new Font("Verdana", 12);
//Get the size of the area to be drawn then convert it to a rect
sizeTextSize = g.MeasureString(sText, fNewFont);
rectTextSize = new Rectangle(pointPosition.X, pointPosition.Y, (int)sizeTextSize.Width, (int)sizeTextSize.Height);
//Draw a white rect
g.FillRectangle(Brushes.White, rectTextSize);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString(sText, fNewFont, Brushes.Black, pPos);
}
//Save the changed image
newBmp.Save(sFilePath, myImageCodecInfo, myEncoderParameters);
}
catch
{
return false;
}
return true;
}
static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
}

Categories

Resources