Hi I have the issue that when I use ScaleTransform(zoomFactor,zoomFactor) the image saved on disk is the original version always, while on screen in the picturebox the image is distorted in proportion to the zoomFactor. Why this could be happening ? Shouldn't I have the final result as applied from e.Graphics on disk written image ?
My code is the following which is a version with matrix. but the instead of matrix I have used the ScaleTransform as well. Result is always the same:
g=e.Graphics;//inside picturebox_paint()
g.ScaleTransform(ratio * zoomFac, ratio * zoomFac);
e.Graphics.DrawImage((Bitmap)bmp, 0, 0);
int seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
String destinationFile = @"C:\tmp\photoid\" + new Random(seed).Next() + "_conv.jpg";
//Here I get always the original image back!!!!
bmp.Save(destinationFile);
I have used as well the following idiom but with same results:
//Matrix matrix = new Matrix();
//matrix.Scale(zoomFac, zoomFac);
//e.Graphics.Transform = matrix;
You need to make the
PictureBox
draw the things it shows on screen into a new Bitmap, which you then can save!As it is the
Image
will be saved in the original form and nothing you did in thePaint
event, which actually painst onto the surface of thePictureBox
will be saved.So to save everything, i.e. The
Image
, possibly aBackgroundImage
and all you draw in thePaint
event you would callDrawToBitmap
somehwere.Somewhere means somewhere else, not in the
Paint
event, as it will call thePaint
event to create the newBitmap
, causing an endless loop..To call it you would do something like this:
But maybe this is not really what you want? Maybe you actually want to modify the
Image
? In that case do not use thePaint
event at all!Instead do something like this:
You could call this from somewhere where the scaling is being triggered from.
Note that doing the scaling repeatedly and each time from the previoulsy scaled version will degrade the quality rather fast. For this always scale from a saved version of the original!!
Btw: Using a
Matrix
for scaling doesn't really make a difference overScaleTransform
.But if you want to do a direct scaling why not use the
DrawImage
overload which takes twoRectangles
? This is the most common solution if all you want to to scale and maybe draw other stuff additionally..:And there there is the scaling
Bitmap
constructor:Which I would recommend if all you want is to scale the
Image
. As the other solutions it will not change theImage
displayed until you assign it back into thePictureBox
..:Don't forget to dispose of the old Image..
Been a while since I messed with GDI but I think you need to copy back to the Bitmap here.
Try something like that before bmp.Save
Edit Apologies for not seeing that you were copying back to the bitmap. Perhaps the overload which specifies the output rectangle is what you need. Try a DrawImage overload which has the destination Rect. https://msdn.microsoft.com/en-us/library/ms142040(v=vs.110).aspx