I am getting insufficient memory exception when i am trying to render a image(10000 X 10000) resolution with canvas(10000 X 10000) resolution.
bmp = new RenderTargetBitmap((int)width, (int(height),graphics.DpiX,graphics.DpiY,PixelFormats.Default)bmp.Render(vs);
dc.PushTransform(new TranslateTransform(difX + left - horizontalScale, difY + top - verticalScale));
dc.PushTransform(new ScaleTransform(1, 1));
// Ask canvas to draw overlays
drawingCanvas.Draw(dc);
// Restore old actual scale.
drawingCanvas.ActualScale = oldActualScale;
// Restore clip
drawingCanvas.RefreshClip();
dc.Pop();
dc.Pop();
dc.Pop();
dc.Close();
width = (Utilityhelper.GetDIPIndependentHorizontal(rect.Width));
height = (Utilityhelper.GetDIPIndependentVertical(rect.Height));
bmp = new RenderTargetBitmap((int)width, (int)(height), Utilityhelper.graphics.DpiX, Utilityhelper.graphics.DpiY, PixelFormats.Default);
if (bmp != null)
{
bmp.Render(vs);
}
Done with using this.... DecodePixelWidth & DecodePixelHeight http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.decodepixelwidth(v=vs.110).aspx
Related
I am developing an application for image processing. To zoom the image, I enlarge PictureBox. But after enlarging I get below image as result.
But I want result like below image
Here is my Code :
picturebox1.Size = new Size((int)(height * zoomfactor), (int)
(width* zoomfactor));
this.picturebox1.Refresh();
The PictureBox by itself will always create a nice and smooth version.
To create the effect you want you need to draw zoomed versions yourself. In doing this you need to set the
Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
Then no blurring will happen..
Example:
private void trackBar1_Scroll(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)pictureBox1.Image;
Size sz = bmp.Size;
Bitmap zoomed = (Bitmap)pictureBox2.Image;
if (zoomed != null) zoomed.Dispose();
float zoom = (float)(trackBar1.Value / 4f + 1);
zoomed = new Bitmap((int)(sz.Width * zoom), (int)(sz.Height * zoom));
using (Graphics g = Graphics.FromImage(zoomed))
{
if (cbx_interpol.Checked) g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawImage(bmp, new Rectangle( Point.Empty, zoomed.Size) );
}
pictureBox2.Image = zoomed;
}
Of course you need to avoid setting the PBox to Sizemode Zoom or Stretch!
I have an image 3519 X 2495 with some logo and text next to it. When the image is opened, i see the logo and the text next to it in the center. I would like to resize the image to 768 X 1004 and want both the logo and the text next to it to appear on the top. When I resize the image I get the logo and text next to it in the center.
Is there a good way to achieve this in c#.
I tried the below code
Image image = Image.FromFile(#"D:\SSH\Automation\ImageResize\Diageo.jpg");
Bitmap bitmap = new Bitmap(768, 1004);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.DrawImage(image, 0, 0, 768, 1004);
bitmap.Save(#"D:\SSH\Automation\ImageResize\Diageo.png");
graphics.Dispose();
To resize an image and keep its initial aspect ratio use the following code:
Note that I use usings from the IDisposable interface instead of calling Dispose myself as this is considered best practice and is safer.
int maxWidth = 768;
int maxHeight = 1004;
using (Bitmap bitmap = new Bitmap(filePath))
{
int width = (int)(bitmap.Width * (maxHeight / (float)bitmap.Height));
int height = maxHeight;
if (bitmap.Height * (maxWidth / (float)bitmap.Width) <= maxHeight)
{
width = maxWidth;
height = (int)(bitmap.Height * (maxWidth / (float)bitmap.Width));
}
using (Bitmap resizedBitmap = new Bitmap(width, height))
{
resizedBitmap.SetResolution(bitmap.HorizontalResolution, bitmap.VerticalResolution);
using (Graphics g = Graphics.FromImage(resizedBitmap))
{
g.DrawImage(bitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height);
}
//Use resizedBitmap here
}
}
I am writing a Windows Phone 8.1 (WINRT) App. I am using fileopenpicker to choose a picture from gallery and then i display it in my app. But i want that user can crop this image before getting displayed on app.
In windows phone 8, we used Photochooser task having width property and cropping options automatically used to come.
Now I am trying to use this :
Windows Phone 8.0: Image Crop With Rectangle
But there is no WriteableBitmap.Pixels in Windows Phone 8.1. What to use instead of WriteableBitmap.Pixels?
// Create a new WriteableBitmap. The size of the bitmap is the size of the cropping rectangle
// drawn by the user, multiplied by the image size ratio.
WB_CroppedImage = new WriteableBitmap((int)(widthRatio * Math.Abs(Point2.X - Point1.X)), (int)(heightRatio * Math.Abs(Point2.Y - Point1.Y)));
// Calculate the offset of the cropped image. This is the distance, in pixels, to the top left corner
// of the cropping rectangle, multiplied by the image size ratio.
int xoffset = (int)(((Point1.X < Point2.X) ? Point1.X : Point2.X) * widthRatio);
int yoffset = (int)(((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);
// Copy the pixels from the targeted region of the source image into the target image,
// using the calculated offset
if (WB_CroppedImage.Pixels.Length > 0)
{
for (int i = 0; i < WB_CroppedImage.Pixels.Length; i++)
{
int x = (int)((i % WB_CroppedImage.PixelWidth) + xoffset);
int y = (int)((i / WB_CroppedImage.PixelWidth) + yoffset);
WB_CroppedImage.Pixels[i] = WB_CapturedImage.Pixels[y * WB_CapturedImage.PixelWidth + x];
}
// Set the source of the image control to the new cropped bitmap
FinalCroppedImage.Source = WB_CroppedImage;
}
else
{
FinalCroppedImage.Source = null;
}
You should take a look at BitmapEncoder and BitmapDecoder classes.
Also you probably will be able to use BitmapBounds to crop your image - set 'X' and 'Y' along with 'Width' and 'Height'.
I think the code may look like this (but I've not tested it):
StorageFile destination; // your destination file
using (var sourceStream = await sourceFile.OpenAsync(FileAccessMode.Read))
{
BitmapDecoder bmpDecoder = await BitmapDecoder.CreateAsync(sourceStream);
// here you scale your image if needed and crop by setting X, Y, Width and Height
BitmapTransform bmpTransform = new BitmapTransform() { ScaledHeight = scaledHeight, ScaledWidth = scaledWidth, InterpolationMode = BitmapInterpolationMode.Cubic, Bounds = new BitmapBounds { X = topLeftX, Y = topLeftY Width = desiredSizeW, Height = desiredSizeH } };
PixelDataProvider pixelData = await bmpDecoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, bmpTransform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);
using (var destFileStream = await destination.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder bmpEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, destFileStream);
// here you need to set height and width - take from above
bmpEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, desiredSizeW, desiredSizeH, 300, 300, pixelData.DetachPixelData());
await bmpEncoder.FlushAsync();
}
}
Of course you don't need to save the edited picture to StorageFile - I've used it as an example, you can write to stream and then set your image source.
Actually i am using drawingContext.DrawRectangle method for drawing rectangle on canvas..
i want to add shadow effect on rectangle..
drawingContext.DrawRectangle(new SolidColorBrush(graphicsObjectFillColor),
new Pen(new SolidColorBrush(ObjectColor), ActualLineWidth),
Rectangle);
or i am using this to add drop shadow..
DropShadowEffect effect = new DropShadowEffect();
effect = new DropShadowEffect { Color = Colors.Black, Direction = -45, Opacity = 0.5, ShadowDepth = 4};
this.Effect = effect;
the shadow is showing but add the time of draw all tool on image tha shodow is not shawing
i am using
DrawingVisual vs = new DrawingVisual();
DrawingContext dc = vs.RenderOpen();
// Draw image
dc.DrawImage(image.Source, rect);
double scale = width / image.Source.Width;
// Keep old existing actual scale and set new actual scale.
double oldActualScale = drawingCanvas.ActualScale;
drawingCanvas.ActualScale = oldActualScale;
// Remove clip in the canvas - we set our own clip.
drawingCanvas.RemoveClip();
// Prepare drawing context to draw graphics
rect = new Rect(left, top, width, height);
dc.PushClip(new RectangleGeometry(rect));
double horizontalScale = Math.Abs((positionDrawingCanvas.X) - (positionImage.X));
double verticalScale = Math.Abs((positionDrawingCanvas.Y) - (positionImage.Y));
double difX = 0.0;
double difY = 0.0;
//if (horizontalScale != 0 && verticalScale != 0)
//{
// //horizontalScale = Math.Abs((positionDrawingCanvas.X + Math.Abs((positionImage.X / sliderScale.Value - positionImage.X))) - (positionImage.X));
// //verticalScale = Math.Abs((positionDrawingCanvas.Y + Math.Abs((positionImage.Y / sliderScale.Value - positionImage.Y))) - (positionImage.Y));
// difX = (positionImage.X - positionImage.X / sliderScale.Value);
// difY = (positionImage.Y - positionImage.Y / sliderScale.Value);
//}
dc.PushTransform(new TranslateTransform(difX + left - horizontalScale, difY+top - verticalScale));
dc.PushTransform(new ScaleTransform(1, 1));
// Ask canvas to draw overlays
drawingCanvas.Draw(dc);
// Restore old actual scale.
drawingCanvas.ActualScale = oldActualScale;
// Restore clip
drawingCanvas.RefreshClip();
dc.Pop();
dc.Pop();
dc.Pop();
dc.Close();
width = (Utilityhelper.GetDIPIndependentHorizontal(rect.Width));
height = (Utilityhelper.GetDIPIndependentVertical(rect.Height));
bmp = new RenderTargetBitmap((int)width, (int)(height), Utilityhelper.graphics.DpiX, Utilityhelper.graphics.DpiY, PixelFormats.Default);
//bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
bmp.Render(vs);
sliderScale.Value = oldScale;
//imageBackground.Stretch = Stretch.Uniform;
//drawingCanvas.Width = (Utilityhelper.GetDIPDependentHorizontal(drawingCanvas.Width));
//drawingCanvas.Height = (Utilityhelper.GetDIPDependentVertical(drawingCanvas.Height));
return bmp;
You have to just change your render method
RenderTargetBitmap bmp = new RenderTargetBitmap((int)width, (int)(height), DpiX, DpiY, PixelFormats.Default);
BitmapSource source = null;
if (bmp != null)
{
bmp.Render(image);
bmp.Render(drawingCanvas);
source = bmp;
}
Here is how you get image (bitmap) from visual in wpf:
// render content into image
var render = new RenderTargetBitmap((int)ContentPresenter.RenderSize.Width, (int)ContentPresenter.RenderSize.Height, 96, 96, PixelFormats.Default);
render.Render(ContentPresenter);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(render));
using (var stream = new MemoryStream())
{
// create bitmap image
encoder.Save(stream);
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = stream;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
bitmap.Freeze();
// use BitmapImage
...
}
ContentPresenter is some visual.
I have a BitmapImage that I want to get the PixelHeight and PixelWidth properties so I can determine whether it has a landscape or portrait layout. After I determine its layout, I need to set either the height or width of the image to get it to fit into my image viewer window without distorting the height:width ratio. However, it appears I have to call BeginInit() in order to do anything with my image. I have to call EndInit() to get the PixelHeight or PixelWidth properties and I cannot call BeginInit() more than once on the same BitmapImage object. So how can I possibly set my image, get the height and width, determine its orientation and then resize the image?
Here the chunk of code that I have been working with:
image.BeginInit();
Uri imagePath = new Uri(path + "\\" + die.Die.ImageID + "_" + blueTape + "_BF.BMP");
image.UriSource = imagePath;
//image.EndInit();
imageHeight = image.PixelHeight;
imageWidth = image.PixelWidth;
//image.BeginInit();
// If the image is taller than it is wide, limit the height of the image
// i.e. DML87s and all non-rotated AOI devices
if (imageHeight > imageWidth)
{
image.DecodePixelHeight = 357;
}
else
{
image.DecodePixelWidth = 475;
}
image.EndInit();
When I run this, I get this run-time exception:
InvalidOperationException:
BitmapImage initialization is not complete. Call the EndInit method to
complete the initialization.
Does anybody know how to deal with this issue?
As far as I know, what you want to do is not possible without decoding the bitmap twice.
I guess it would be a lot simpler to just decode the bitmap to its native size and then set the size of the containing Image control as needed. The bitmap is scaled appropriately, as Stretch is set to Uniform (since both width and height of the Image control are set, Stretch could as well be set to Fill or UniformToFill).
var bitmap = new BitmapImage(new Uri(...));
if (bitmap.Width > bitmap.Height)
{
image.Width = 475;
image.Height = image.Width * bitmap.Height / bitmap.Width;
}
else
{
image.Height = 475;
image.Width = image.Height * bitmap.Width / bitmap.Height;
}
image.Stretch = Stretch.Uniform;
image.Source = bitmap;