I try to get aspect ratio of downloaded images. For this purpose I need height and width, but everytime and everyway I try, I get only 0.0 or NaN. I tried Image and BitmapImage. I tried to set Stretch, one of the sizes in hope the other one will be filled automatically.
Both of them don't have set sizes I can read:
Image image = new Image();
image.Source = new BitmapImage(new Uri(customItem.FullURL, UriKind.Absolute));
BitmapImage bitmap = new BitmapImage(new Uri(customItem.FullURL));
The size of the image is not available until it is open. Test for width and height in the ImageOpened event handler.
Code
var bitmap = new BitmapImage(new Uri(uri));
// ImageOpened fires when image is downloaded and decoded
bitmap.ImageOpened += (s, args) =>
{
var w = bitmap.PixelWidth;
};
// setting the source causes the ImageOpened or ImageFailed event to fire.
// image2 must be in visual tree
image2.Source = bitmap;
You can try using the WebClient as suggested in this answer.
using System.Drawing;
using System.Net;
using System.IO;
using System.Windows.Forms;
WebClient wc = new WebClient();
using (MemoryStream ms = new MemoryStream(wc.DownloadData(customItem.FullURL))) {
Image img = Image.FromStream(ms);
MessageBox.Show(img.Height.ToString() + " -- " + img.Width.ToString());
}
Try this (Just replace my url string with your url string):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Net;
namespace GDI
{
class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
Bitmap bmp = new Bitmap(wc.OpenRead("https://s0.2mdn.net/viewad/3092927/Freedom_AW_D_Zenith_119053_DS_Apple_Pay_Bleachers_300x250.jpg"));
Console.WriteLine("Width=" + bmp.Width.ToString() + ", Height=" + bmp.Height.ToString());
Console.ReadLine();
}
}
}
May be this code will helpful for you:
Image image = System.Drawing.Image.FromFile("\1.jpg"); Console.Write("Width: " + image.Width + ", Height: " + image.Height);
Related
I am attempting to save an embedded shape as an image using C#.
If the object is embedded as an actual image (WMF/JPEG) I can retrieve the image without issue but when the object is an embedded shape or an OLE Object that displays as an image in Word I cannot seem to extract or retrieve said object to then either copy to the clipboard or save said image.
Here is my current code sample; either the object is empty or I get the following error:
System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI+.'
Any help is appreciated. Thank you
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ImageMagickSandboxWinForms
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
public static BitmapSource ConvertBitmap(Bitmap source)
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
source.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
private void button1_Click(object sender, EventArgs e)
{
string physicsDocLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
physicsDocLocation += #"\[Doc path Here].docx";
var wordApp = new Microsoft.Office.Interop.Word.Application();
var wordDoc = wordApp.Documents.Open(physicsDocLocation);
int iCount = wordDoc.InlineShapes.Count;
for (int i = 1; i < (wordDoc.InlineShapes.Count + 1); i++)
{
var currentInlineShape = wordDoc.InlineShapes[i];
currentInlineShape.Range.Select();
wordDoc.ActiveWindow.Selection.Range.Copy();
BitmapSource clipBoardImage = System.Windows.Clipboard.GetImage();
Bitmap bmpClipImage = BitmapFromSource(clipBoardImage);
string finalPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), #"TestConversions");
finalPath += #"\" + Guid.NewGuid().ToString() + ".jpg";
using (MemoryStream memory = new MemoryStream())
{
using (FileStream fs = new FileStream(finalPath, FileMode.Create, FileAccess.ReadWrite))
{
bmpClipImage.Save(memory, ImageFormat.Jpeg); <<<---- Error happens here.
byte[] bytes = memory.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
}
wordDoc.Close();
wordApp.Quit();
}
}
}
i have these code in my library, dunno where i have found that but hope you do the job for you: i am using Clippboard to trap the different images, jus t dont forget, Thread is needed to access Clipboard
for (var i = 1; i <= wordApplication.ActiveDocument.InlineShapes.Count; i++)
{
var inlineShapeId = i;
var thread = new Thread(() => SaveInlineShapeToFile(inlineShapeId, wordApplication));
// STA is needed in order to access the clipboard
// https://stackoverflow.com/a/518724/700926
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
// General idea is based on: https://stackoverflow.com/a/7937590/700926
protected static void SaveInlineShapeToFile(int inlineShapeId, Application wordApplication)
{
// Get the shape, select, and copy it to the clipboard
var inlineShape = wordApplication.ActiveDocument.InlineShapes[inlineShapeId];
inlineShape.Select();
wordApplication.Selection.Copy();
// Check data is in the clipboard
if (Clipboard.GetDataObject() != null)
{
var data = Clipboard.GetDataObject();
// Check if the data conforms to a bitmap format
if (data != null && data.GetDataPresent(DataFormats.Bitmap))
{
// Fetch the image and convert it to a Bitmap
var image = (Image) data.GetData(DataFormats.Bitmap, true);
var currentBitmap = new Bitmap(image);
// Save the bitmap to a file
currentBitmap.Save(#"C:\Users\Username\Documents\" + String.Format("img_{0}.png", inlineShapeId));
}
}
}
following if you are using Winform or WPF the clipboard acts differently for an image:
if (Clipboard.ContainsImage())
{
// ImageUIElement.Source = Clipboard.GetImage(); // does not work
System.Windows.Forms.IDataObject clipboardData = System.Windows.Forms.Clipboard.GetDataObject();
if (clipboardData != null)
{
if (clipboardData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
{
System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)clipboardData.GetData(System.Windows.Forms.DataFormats.Bitmap);
ImageUIElement.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
Console.WriteLine("Clipboard copied to UIElement");
}
}
}
after if its not functionam due to a bug in translation of format, there is this solution . So its infrecnh but its easily to understand the logic of the using of "DeviceIndependentBitmap"
I am running the following code to get a logo screenshot but as it seems that location and size of element doesn't work when the element is in iframe. How element screenshot works in iframe ?
using System;
using System.Drawing;
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var _driver = new ChromeDriver();
_driver.Navigate().GoToUrl("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe");
_driver.SwitchTo().Frame("iframeResult");
_driver.SwitchTo().Frame(_driver.FindElement(OpenQA.Selenium.By.XPath("//iframe[#src='https://www.w3schools.com']")));
IWebElement element = _driver.FindElement(OpenQA.Selenium.By.XPath("//a[#class='w3schools-logo']"));
Console.WriteLine(element.Location); //Return 0
Console.WriteLine(element.Size); //Return 0
Screenshot sc = ((ITakesScreenshot)_driver).GetScreenshot();
using (var img = Image.FromStream(new MemoryStream(sc.AsByteArray)) as Bitmap)
{
img?.Clone(new Rectangle(element.Location, element.Size), img.PixelFormat).Save(#"C:\test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
I have found a solution
new Actions(_driver).MoveToElement(element).Build().Perform();
Thread.Sleep(1000);
var sc = ((ITakesScreenshot) _driver).GetScreenshot();
var remoteWebElement = element as RemoteWebElement;
using (var img = Image.FromStream(new MemoryStream(sc.AsByteArray)) as Bitmap)
{
if (remoteWebElement != null)
img?.Clone(new Rectangle(remoteWebElement.LocationOnScreenOnceScrolledIntoView,remoteWebElement.Size), img.PixelFormat).Save(file, ImageFormat.Jpeg);
}
I want to show the thumbnail image of url in picture box. here is a code i am trying
var request = WebRequest.Create("http://www.facebook.com");
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
pictureBox1.Image = Bitmap.FromStream(stream);
}
The code is not working, or saying no response
here i have used this tecnique
using System;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Facebook;
using System.Net;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
public Bitmap GenerateScreenshot(string url)
{
// This method gets a screenshot of the webpage
// rendered at its full size (height and width)
return GenerateScreenshot(url, -1, -1);
}
public Bitmap GenerateScreenshot(string url, int width, int height)
{
// Load the webpage into a WebBrowser control
WebBrowser wb = new WebBrowser();
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(url);
while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }
// Set the size of the WebBrowser control
wb.Width = width;
wb.Height = height;
if (width == -1)
{
// Take Screenshot of the web pages full width
wb.Width = wb.Document.Body.ScrollRectangle.Width;
}
if (height == -1)
{
// Take Screenshot of the web pages full height
wb.Height = wb.Document.Body.ScrollRectangle.Height;
}
// Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
wb.Dispose();
return bitmap;
}
private void button1_Click(object sender, EventArgs e)
{
string pc = textBox1.Text;
Bitmap thumbnail = GenerateScreenshot(textBox1.Text, 1024, 598);
thumbnail = GenerateScreenshot(pc);
// Display Thumbnail in PictureBox control
pictureBox1.Image = thumbnail;
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace convert
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load_1(object sender, EventArgs e)
{
// Image image = Image.FromFile(#"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg");
// Set the PictureBox image property to this image.
// ... Then, adjust its height and width properties.
// pictureBox1.Image = image;
//pictureBox1.Height = image.Height;
//pictureBox1.Width = image.Width;
string strFileName = #"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg";
Bitmap bitmap = new Bitmap(strFileName);
//bitmap.Save("testing.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
pictureBox1.Image = bitmap;
pictureBox1.Height = bitmap.Height;
pictureBox1.Width = bitmap.Width;
}
}
}
I am using the above code for converting jpg file into bitmap. It works but I need to know how to stream the jpg image and convert it into bitmap then display the bitmap image with out storing it. I am using c# and vb.net
Try this to convert to Bitmap :
public Bitmap ConvertToBitmap(string fileName)
{
Bitmap bitmap;
using(Stream bmpStream = System.IO.File.Open(fileName, System.IO.FileMode.Open ))
{
Image image = Image.FromStream(bmpStream);
bitmap = new Bitmap(image);
}
return bitmap;
}
Possibly easier:
var bitmap = new Bitmap(Image.FromFile(path));
Need a little help here. I have a app that I am creating that mergies two pictures together. The issue is when i am trying to convert the bitmap into a bitmpaimage to display the result on the screen. from what i can tell, the image is not being save to the memory stream at "NwImg.Save(memory,ImageFormat.Jpeg);" Any ideas??
//The Code
//bitmap to bitmapimage conversion
using (MemoryStream memory = new MemoryStream())
{//NwImg is type Bitmap, and at this point i checked properties and values did copy over from the merging
NwImg.Save(memory, ImageFormat.Jpeg);//here image NwImg.save is suppose to transfer to memory
memory.Position = 0;
Nwbi.StreamSource = memory;//memory stream is showing null
Nwbi.CacheOption = BitmapCacheOption.OnLoad;
}
I don't know if this matter but NwImg represents a bitmap that was created by merging a png image on top of a jpeg. I didn't read anything that said it matter but i figured i would through that in there.
/// here is all the code as requested david
//Main c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
namespace PicMerger2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Pic currentPic = new Pic();
BitmapImage bi = new BitmapImage(new Uri("\\original photo.jpg"));
BitmapImage Nwbi = new BitmapImage();
public MainWindow()
{
InitializeComponent();
OriginalPhoto.Source = bi;
ResultPhoto.Source = Nwbi;
}
private void apply_Click(object sender, RoutedEventArgs e)
{
Bitmap NwImg;
//bitmapimage to bitmap conversion
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bi));
enc.Save(outStream);
System.Drawing.Bitmap MarkThisPic = new System.Drawing.Bitmap(outStream);
// return bitmap; <-- leads to problems, stream is closed/closing ...
NwImg = new Bitmap(MarkThisPic);
}
NwImg = currentPic.MergerTheseTwo(NwImg);
//bitmap to bitmapimage conversion
using (MemoryStream memory = new MemoryStream())
{
NwImg.Save(memory, ImageFormat.Jpeg);
memory.Position = 0;
Nwbi.StreamSource = memory;
Nwbi.CacheOption = BitmapCacheOption.OnLoad;
}
ResultPhoto.Source = Nwbi;
}
}
}
//Main xaml
<Window x:Class="PicMerger2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<StackPanel>
<Image x:Name="OriginalPhoto" Height="200" Stretch="UniformToFill" Source="{Binding}"></Image>
<Label>Original Images</Label>
</StackPanel>
<Button x:Name="apply" Click="apply_Click" Height="25" >Apply Watermark</Button>
<StackPanel>
<Image x:Name="ResultPhoto" Height="200" Stretch="UniformToFill" Source="{Binding}"></Image>
<Label>Watermarked Image</Label>
</StackPanel>
</StackPanel>
</Grid>
</Window>
// pic class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace PicMerger2
{
class Pic
{
Bitmap Watermark = new Bitmap(PicMerger2.Properties.Resources._Watermark);
public Bitmap MergerTheseTwo(Bitmap BottomImage)
{
try
{
using (var canvas = Graphics.FromImage(BottomImage))
{
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
// canvas.DrawImage(BottomImage, new Rectangle(0, 0, BottomImage.Width, BottomImage.Height), new Rectangle(0, 0, BottomImage.Width, BottomImage.Height), GraphicsUnit.Pixel);
canvas.DrawImage(Watermark, 0, 0);
canvas.Save();
//Save to current picture
Bitmap NewImage = new Bitmap(BottomImage.Width, BottomImage.Height, canvas);
return NewImage;
}
}
catch (Exception)
{
throw;
}
}
}
}
You will need to change a couple of things so that your code can work.
Use the following code for the Bitmap to BitmapImage conversion.
using (MemoryStream memory = new MemoryStream())
{
NwImg.Save(memory, ImageFormat.Jpeg);
memory.Position = 0;
Nwbi = new BitmapImage();
Nwbi.BeginInit();
Nwbi.StreamSource = memory;
Nwbi.CacheOption = BitmapCacheOption.OnLoad;
Nwbi.EndInit();
}
Inside your Pic class, replace these lines
//Save to current picture
Bitmap NewImage = new Bitmap(BottomImage.Width, BottomImage.Height, canvas);
return NewImage;
to this
return BottomImage;
since the overload of the Bitmap class that you are using, doesn't create a new bitmap based on the Graphics object but just its resolution (this results to an empty image). So, since you draw onto the BottomImage bitmap, you just need to return that image.
The variable "memory" cannot possibly be null on the line where you commented "memory stream is showing null" when that line executes because it is definitely assigned in the "using" block 4 lines above it. I'm guessing you put a debugger breakpoint too early in the method. Try putting your breakpoint on the line where you assign Nwbi.CacheOption and see if the debugger tells you what you expected.