I am trying to create a bitmap and all I have is the savedUri and the imagePath. I believe I am retrieving the imagePath correctly because when I go and look at the actual properties of the photos of the photo and the logged path they are the same so I believe it is a problem in the way I'm creating the bitmap. Here is the code I use:
if (_bitmap == null)
{
string imagePath = null;
try
{
imagePath = GetRealPathFromURI(_saveUri);
LogManager.Info("********the image path is", imagePath);
}
catch
{
imagePath = _saveUri.Path;
}
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.InJustDecodeBounds = true;
BitmapFactory.DecodeFile(imagePath, options);
var width = (int)Math.Round(_outputX * 0.5);
var heigth = (int)Math.Round(_outputY * 0.5);
options.InSampleSize = BitmapTools.CalculateInSampleSize(options, width, width * heigth);
options.InJustDecodeBounds = false;
options.InDensity = 160;
try
{
_bitmap = BitmapFactory.DecodeFile(imagePath, options);
}
catch
{
GC.Collect();
_bitmap = BitmapFactory.DecodeFile(imagePath, options);
}
}
if (_bitmap == null)
LogManager.Info("********the bitmap width is: ", "well bloody hell the bitmap is null");
else
LogManager.Info("********the bitmap width is: ", _bitmap.Width.ToString());
On the last two lines the bitmap is never null but it always has a width of 1 and when I display it there is no image. This is for creating, displaying and saving an image on Monodroid but that isn't too relevant to this question as it is.
Related
I'm trying to minify image from url, my code is this
public static string GetBreaker(string fileName)
{
string cacheBreaker = null;
try
{
if (fileName.StartsWith("~"))
{
fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName.Remove(0));
}
cacheBreaker = File.GetLastWriteTime(fileName).ToFileTime().ToString();
}
catch { }
return string.IsNullOrEmpty(cacheBreaker) ? string.Empty : string.Format("?cachebreaker={0}", cacheBreaker);
}
public static void SaveJpeg(string path, System.Drawing.Image img, int quality)
{
if (quality < 0 || quality > 100)
throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");
EncoderParameter qualityParam =
new EncoderParameter(Encoder.Quality, quality);
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
protected void Button1_Click(object sender, EventArgs e)
{
System.Drawing.Image myImage = System.Drawing.Image.FromFile(ImageUrltxt.Text.ToString());
SaveJpeg(#"~/mintemp/demo.jpg", myImage, 50);
}
I'm getting error like this:
URI formats are not supported.
in
System.Drawing.Image myImage = System.Drawing.Image.FromFile(ImageUrltxt.Text.ToString());
Can anyone help me to solve out this problem. I'm very new to programming. Thanks in advance, sorry for my bad English.
1. First you have to check out your uri path is correct or not eg:
string uriPath = "file:\\C:\\Users\\john\\documents\\visual studio 2010\\Projects\\proj";
or
string localPath = new Uri(uriPath).LocalPath;
2. You have to add the uri of the image as correct Please check your uri path of image is correct.
SaveJpeg(#"~/mintemp/demo.jpg", myImage, 50);
3. This is coded in c# (for reference) resizing and compressing of image in c#
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
private Boolean CheckFileType(String fileName)
{
String ext = Path.GetExtension(fileName) ;
switch (ext.ToLower())
{
case ".gif":
return true;
case ".png":
return true;
case ".jpg":
return true;
case ".jpeg":
return true;
case ".bmp":
return true;
default:
return false;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
const int bmpW = 300;// //New image target width
const int bmpH = 226;// //New Image target height
if (FileUpload1.HasFile)
{
//Clear the error label text
lblError.Text = "";
//Check to make sure the file to upload has a picture file format extention
//and set the target width and height
if (this.CheckFileType(FileUpload1.FileName))
{
Int32 newWidth = bmpW;
Int32 newHeight = bmpH;
//Use the uploaded filename for saving without the "." extension
String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf("."));
//Mid(FileUpload1.FileName, 1, (InStr(FileUpload1.FileName, ".") - 1)) ;
//Set the save path of the resized image, you will need this directory already created in your web site
String filePath = "~/Upload/" + upName + ".jpg";
//Create a new Bitmap using the uploaded picture as a Stream
//Set the new bitmap resolution to 72 pixels per inch
Bitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream);
Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newBmp.SetResolution(72, 72);
//Get the uploaded image width and height
Int32 upWidth = upBmp.Width;
Int32 upHeight = upBmp.Height;
Int32 newX = 0; //Set the new top left drawing position on the image canvas
Int32 newY = 0;
Decimal reDuce;
//Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
//to ensure the image is always in the centre of the canvas vertically and horizontally
if (upWidth > upHeight)
{
//Landscape picture
reDuce = newWidth / upWidth;
//calculate the width percentage reduction as decimal
newHeight = ((Int32)(upHeight * reDuce));
//reduce the uploaded image height by the reduce amount
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
newX = 0; //Picture will be full width
}
else
{
if (upWidth < upHeight)
{
//Portrait picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = 0; //Picture will be full hieght
}
else
{
if (upWidth == upHeight)
{
//square picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)((upWidth * reDuce)));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)(((bmpW - newWidth) / 2))); //Position the image centrally across the canvas
newY = ((Int32)(((bmpH - newHeight) / 2))); //Position the image centrally down the canvas
}
}
}
//Create a new image from the uploaded picture using the Graphics class
//Clear the graphic and set the background colour to white
//Use Antialias and High Quality Bicubic to maintain a good quality picture
//Save the new bitmap image using //Png// picture format and the calculated canvas positioning
Graphics newGraphic = Graphics.FromImage(newBmp);
try
{
newGraphic.Clear(Color.White);
newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight);
newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg);
//Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath;
Image1.Visible = true;
}
catch (Exception ex)
{
lblError.Text = ex.ToString();
throw ex;
}
finally
{
upBmp.Dispose();
newBmp.Dispose();
newGraphic.Dispose();
}
}
else
{
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png.";
}
}
}
}
I have made a program which monitors the clipboard and when a new image is copied, it gets saved to a file. Now when I copy an image from Paint.net which has transparent background, the background gets filled with white but when I copy the same image from Firefox it saves fine. Here is the test image i'm using: https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png and here is the code which I use to get the image from clipboard:
private Image GetImageFromClipboard()
{
if (Clipboard.GetDataObject() == null) return null;
if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Dib))
{
var dib = ((System.IO.MemoryStream)Clipboard.GetData(DataFormats.Dib)).ToArray();
var width = BitConverter.ToInt32(dib, 4);
var height = BitConverter.ToInt32(dib, 8);
var bpp = BitConverter.ToInt16(dib, 14);
if (bpp == 32)
{
var gch = GCHandle.Alloc(dib, GCHandleType.Pinned);
Bitmap bmp = null;
try
{
var ptr = new IntPtr((long)gch.AddrOfPinnedObject() + 40);
bmp = new Bitmap(width, height, width * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, ptr);
return new Bitmap(bmp);
}
finally
{
gch.Free();
if (bmp != null) bmp.Dispose();
}
}
}
return Clipboard.ContainsImage() ? Clipboard.GetImage() : null;
}
Using the above code, I save the image:
Image img = GetImageFromClipboard();
img.RotateFlip(RotateFlipType.Rotate180FlipX);
img.Save("test.png");
I can also see the transparency in a picturebox when the image is copied from Firefox but not when copied from Paint.net.
This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 7 years ago.
A graph is being generated in a webpage. I am trying to do a screen capture with C# code. I tried the code below. It worked a few times and now I get "index was out of range. must be non-negative and less than the size of the collection" error.
Any help or guidance is appreciated. Thanks in advance.
System.Drawing.Bitmap bitMap = null;
static AutoResetEvent autoEvent;
public void DownloadAsImage(string title, string location)
{
autoEvent = new AutoResetEvent(false);
Uri url = HttpContext.Current.Request.Url;
string RootUrl = url.AbsoluteUri.Replace(url.PathAndQuery, string.Empty);
//ApartmentState:specifies the state of a system.threading.thread
//STA:Thread will create and enter a single-threaded apartment
Thread t = new Thread(CaptureWebPageToDisplay);
t.SetApartmentState(ApartmentState.STA);
if (title == "PieGraph" && location == "0")
{
t.Start(RootUrl + "/_Layouts/AppPage/Reports/TotalGraphPage.aspx?isdlg=1");
Thread.Sleep(30000);
}
else
{
t.Start(RootUrl + "/_Layouts/AppPage/Reports/GraphPage.aspx?isdlg=1&Title=" + title + "&Location=" + location);
Thread.Sleep(10000);
}
autoEvent.Set();
HttpContext.Current.Response.ContentType = "image/jpeg";
string targetFolder = Server.MapPath(#".\GraphImages\") + title + ".Jpeg";
try
{
bitMap.Save(targetFolder);
bitMap.Dispose();
}
catch(Exception ex){
DBLogger.ExpandException(ex);
if (bitMap != null)
{
bitMap.Dispose();
}
}
}
public void CaptureWebPageToDisplay(object URL)
{
// create a hidden web browser, which will navigate to the page
System.Windows.Forms.WebBrowser web = new System.Windows.Forms.WebBrowser();
// Full web browser
web.Dock = System.Windows.Forms.DockStyle.Fill;
web.Size = new System.Drawing.Size(1000, 800);
// we don't want scrollbars on our image
web.ScrollBarsEnabled = false;
// don't let any errors shine through
web.ScriptErrorsSuppressed = true;
// let's load up that page!
web.Navigate((string)URL);
// wait until the page is fully loaded
while (web.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(5000); // allow time for page scripts to update
// the appearance of the page
// set the size of our web browser to be the same size as the page
int width = web.Document.Body.ScrollRectangle.Width;
int height = web.Document.Body.ScrollRectangle.Height;
web.Width = width;
web.Height = height;
// a bitmap that we will draw to
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
// change background color to white, just in case
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
g.Clear(System.Drawing.Color.White);
// create rectangle.
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(20, 0, width, height);
// draw the web browser to the bitmap
web.DrawToBitmap(bmp, rect);
bitMap = bmp;
}
I think the following code to capture a screen might help :
public static void CaptureScreen(double x, double y, double width, double height)
{
int ix, iy, iw, ih;
ix = Convert.ToInt32(x);
iy = Convert.ToInt32(y);
iw = Convert.ToInt32(width);
ih = Convert.ToInt32(height);
Bitmap image = new Bitmap(iw, ih,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(image);
g.CopyFromScreen(ix, iy, ix, iy,
new System.Drawing.Size(iw, ih),
CopyPixelOperation.SourceCopy);
// Download Image
image.Save(FileName, ImageFormat.Png);
}
I tried this:
string str = System.IO.Path.GetFileName(txtImage.Text);
string pth = System.IO.Directory.GetCurrentDirectory() + "\\Subject";
string fullpath = pth + "\\" + str;
Image NewImage = clsImage.ResizeImage(fullpath, 130, 140, true);
NewImage.Save(fullpath, ImageFormat.Jpeg);
public static Image ResizeImage(string file, int width, int height, bool onlyResizeIfWider)
{
if (File.Exists(file) == false)
return null;
try
{
using (Image image = Image.FromFile(file))
{
// Prevent using images internal thumbnail
image.RotateFlip(RotateFlipType.Rotate180FlipNone);
image.RotateFlip(RotateFlipType.Rotate180FlipNone);
if (onlyResizeIfWider == true)
{
if (image.Width <= width)
{
width = image.Width;
}
}
int newHeight = image.Height * width / image.Width;
if (newHeight > height)
{
// Resize with height instead
width = image.Width * height / image.Height;
newHeight = height;
}
Image NewImage = image.GetThumbnailImage(width, newHeight, null, IntPtr.Zero);
return NewImage;
}
}
catch (Exception )
{
return null;
}
}
Running the above code, I get an image 4-5 KB in size with very poor image quality.
The original image file is no more than 1.5 MB large. How can I improve the image quality of the results?
I think you should use Image Resizer, its free and resizing an image is very easy using it.
var settings = new ResizeSettings {
MaxWidth = thumbnailSize,
MaxHeight = thumbnailSize,
Format = "jpg"
};
settings.Add("quality", quality.ToString());
ImageBuilder.Current.Build(inStream, outStream, settings);
resized = outStream.ToArray();
You can also install it using Nuget package manager.
PM> Install-Package ImageResizer
I have created a handler for writing text on Image which call a function written below
private bool HavException { get; set; }
private string ExceptionMessage { get; set; }
public Bitmap SourceImage { get; set; }
public Bitmap DestinationImage { get; set; }
public ImageMethods()
{
HavException = false;
ExceptionMessage = string.Empty;
}
public Image AddWatermarkText(Image img, string textOnImage)
{
try
{
textOnImage = ConfigurationManager.AppSettings["textOnImage"];
var opacity = Int32.Parse(ConfigurationManager.AppSettings["opicity"]);
var red = Int32.Parse(ConfigurationManager.AppSettings["red"]);
var green = Int32.Parse(ConfigurationManager.AppSettings["green"]);
var blue = Int32.Parse(ConfigurationManager.AppSettings["blue"]);
var fontSize = Int32.Parse(ConfigurationManager.AppSettings["fontSize"]);
var fontName = ConfigurationManager.AppSettings["fontName"];
var lobFromImage = Graphics.FromImage(img);
var lobFont = new Font(fontName, fontSize, FontStyle.Bold);
var lintTextHw = lobFromImage.MeasureString(textOnImage, lobFont);
var lintTextOnImageWidth = (int)lintTextHw.Width;
var lintTextOnImageHeight = (int)lintTextHw.Height;
var lobSolidBrush = new SolidBrush(Color.FromArgb(opacity, Color.FromArgb(red, green, blue)));
// lobFromImage.Clear(Color.White);
lobFromImage.DrawImage(img, img.Height, img.Width);
var posLeft = (img.Width - lintTextOnImageWidth) / 2;
posLeft = posLeft > 0 ? posLeft : 5;
var lobPoint = new Point(posLeft, (img.Height / 2) - (lintTextOnImageHeight / 2));
// var lobPoint = new Point(RandomNumber(0, img.Width - lintTextOnImageWidth), RandomNumber(0, img.Height - lintTextOnImageHeight));
lobFromImage.DrawString(textOnImage, lobFont, lobSolidBrush, lobPoint);
lobFromImage.Save();
lobFromImage.Dispose();
lobSolidBrush.Dispose();
lobFont.Dispose();
}
catch (Exception ex)
{
HavException = true;
ExceptionMessage = ex.Message;
}
return img;
}
Every thing is working fine but the size of image is getting increased by 2 to three times.
Is there any way that the size does not increase too much. I have jpg as original image.
Thanks
Following call does not make sense and may be the culprit for inflating your image size:
lobFromImage.DrawImage(img, img.Height, img.Width);
This would draw the original image at (height, width) location - for example, if you have 200 x 100 image then above call would draw the image at (100, 200) location and possibly stretching your canvas to 300 x 300 size.
For adding the watermark, all you need to do is to draw the text - so my guess is by removing above line may do the trick.
Also lobFromImage.Save(); looks suspicious - it saves the graphic's object state on stack and doesn't have anything to do with saving the image on the disk.