I am trying to load pictures with the code below:
void LoadPictures(int s)
{
grdScene.Children.Clear();
TabControl tab = new TabControl();
for (int i = s; i <= s+3; i++)
{
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap("C:\\img\\" + i + ".png");
TabItem tabItem = new TabItem();
tabItem.Header = "Scene " + i;
var bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
Image image = new Image();
image.Source = bitmapSource;
tabItem.Content = image;
tab.Items.Add(tabItem);
}
grdScene.Children.Add(tab);//grdScene is Grid
}
it works fine but every time I run this method the memory is going up.
Then I tried to set all the items to null, but no success. Here is the code:
foreach (var child in grdScene.Children)
{
TabControl tab1 = (TabControl)child;
foreach (TabItem item in tab1.Items)
{
Image img = (Image)item.Content;
img = null;
}
tab1 = null;
}
I tried GC.Collect() but nothing changes. What should I do to solve this problem?
Why are you doing this via code-behind?
From the look of your code the tab items are populated entirely by the image.
You could just bind a tabcontrol to the image path collection and use a style to describe the look you're after, it'd be a lot simpler and the WPF core would then be taking care of the image loading and memory management itself.
If that's not usable for you then your issue is coming from how you're loading the image, you're doing it via an unsafe interop method that doesn't release the memory for you, you have to dispose of the bitmap youreself .Dispose()
You'd be better doing: loading the source of a BitmapImage in WPF?
Using BitmapImage is likely the better way to go if you want to remain doing it in the code-behind rather than the Interop methods.
SO:
void LoadPictures(int s)
{
grdScene.Children.Clear();
TabControl tab = new TabControl();
for (int i = s; i <= s + 3; i++)
{
BitmapImage bmp = new BitmapImage(new Uri("C:\\img\\" + i + ".png"));
TabItem tabItem = new TabItem();
tabItem.Header = "Scene " + i;
tabItem.Content = new Image(){Source = bmp};
tab.Items.Add(tabItem);
}
grdScene.Children.Add(tab);
}
Should do the trick.
Try to call Dispose on all IDisposables, such as System.Drawing.Bitmap or better use using..
using(var bmp = new System.Drawing.Bitmap("C:\\img\\" + i + ".png"))
{
.....
}
Related
I want to load the image from the URL to the control.But it loads very slowly and When I clicked on tab 2 and returned to tab 1, the app was stalled.
enter image description here
public void ShowImageFromJsonURL()
{
string json = (new
WebClient()).DownloadString("http://ddragon.leagueoflegends.com/cdn/6.24.1/data/en_US/profileicon.json");
var result = JsonConvert.DeserializeObject<ProfileIcon>(json);
string version = result.Version.ToString();
string type = result.Type;
foreach (var item in result.Data)
{
string url = "http://ddragon.leagueoflegends.com/cdn/" + version + "/img/" + type + "/" + item.Value.Image.Full;
Image image = new Image()
{
Margin = new Thickness(10, 20, 0, 0),
Width = 150,
Height = 150,
Source = new BitmapImage(new Uri(url, UriKind.Absolute))
};
WrapPanelMain.Children.Add(image);
}
}
Apart from all your customers having a better internet connection, here are some options within your control:
A) Save the images with lower quality for quicker downloads.
B) Use a real CDN.
C) Cache the images in WPF app startup.
D) Use Async or a background worker to load the images to avoid the application freezing.
I would like to know if there's a way to display database value on an image, like I have a image template of a certificate and i would like to display name from the database, cause I have like 1000 names and there Image have to be made, is it possible from me to make a c# app for that. Im sorry new to this I did searches but i can't find anything.
Thanks
You can do it by the GDI+ drawing in .NET. first, load your template image, then draw a string to it, then save it as a new image. load all the names from database and process them in a loop, that will be ok. what you must focus on is to find the proper drawing position and beautify the font, my sample is below:
private void btnDrawImage_Click(object sender, EventArgs e)
{
string templateFile = Application.StartupPath + Path.DirectorySeparatorChar + "template_picture.jpg";
//customerize your dispaly string style
Font ft = new System.Drawing.Font("SimSun", 24);
Brush brush = Brushes.Red;
//start position(x,y)
Point startPt = new Point(100, 100);
//names from database
var nameList = new List<string>(){
"scott yang",
"Vivi",
"maxleaf",
"lenka"};
//process image on every name
foreach (string name in nameList)
{
string msg = "Welcome " + name;
Image templateImage = Image.FromFile(templateFile);
Graphics g = Graphics.FromImage(templateImage);
g.DrawString(msg, ft, brush, startPt.X, startPt.Y);
g.Dispose();
string savePath = "c:\\" + name + ".jpg";
templateImage.Save(savePath);
}
}
here is my result, I hope it is helpful to you.
I'm trying to insert images in my rich text box in C#, but so far I'm only failing. Miserably.
This is the code that I am using:
Clipboard.SetImage(Image.FromFile(Application.StartupPath + #"\PIC\" + i + ".bmp"));
chat.Paste();
The real problem is I am not able to put both text and image in the textbox. The moment I insert text after copying the image the image disappears. I am unable to find a solution for this
Can anybody help me with this? Please???
Thanks
RichTextBox rtb = new RichTextBox();
byte[] headerImage = (byte[])(dr["ImageData"]);
string imageData = string.Empty;
if (headerImage != null && headerImage.Length > 0)
{
Bitmap bmp = new Bitmap(new MemoryStream(headerImage));
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0;
imageData = #"{\pict\jpegblip\picw10449\pich3280\picwgoal9924\pichgoal1860\ " + BitConverter.ToString(ms.ToArray()).Replace("-", string.Empty).ToLower() + "}";
ms.Dispose();
}
string finalrtfdata = rtb.Rtf;
finalrtfdata = finalrtfdata.Replace("&ImageHeader&", imageData);
// finalrtfdata contain your image data along with rtf tags.
Try this out,you can paste this into your code and call it:
place a picture into your project to embeded resource,and call this method
passing the richtextbox.
private void createImage(Control item)
{
Hashtable image = new Hashtable(1);
image.Add(item,yourproject.Properties.Resources.yourpicturename);
Clipboard.SetImage((Image)image[item]);
((RichTextBox)item).Paste();
}
private static void createImage(RichTextBox item)
{
var image = new Hashtable(1) { { item, Properties.Resources.yourimage } };
Clipboard.SetImage((Image)image[item]);
item.Paste();
}
I have developed an application that loaded many images in a listview using ImageList in c# .net framework 4. The images are also compressed. When many many images are loaded and compressed then it takes a long time. So I call the method in backgroundworker. In the backgroundworker I had to add images to ImageList and add ImageList to ListView. So I have used safeinvoke() method listView1.SafeInvoke(d=>d.Items.Add(item)).
Everything works fine. Images are displayed one by one in the listview.
But the release of the application doesn’t work properly in some pc and properly works in some other pc. Doesn’t work properly means, If 100 images are browsed using OpenFileDialog to load then some images are loaded and added to listview and then the loading is automatically stopped without adding all images to the listview and no exception shows.
I have spent many times to solve this problem but couldn’t figure out the problem. . Where is the problem? Can anybody help me?
private void bgwLoading_DoWork(object sender, DoWorkEventArgs e)
{
ArrayList a = (ArrayList)e.Argument;
string[] fileNames = (string[])a[0];
this.loadMultiImages(fileNames);
}
private void loadMultiImages(string[] fileNames)
{
int i = 1;
int totalFiles = fileNames.Count();
foreach (string flName in fileNames)
{
if (!flName.Contains("Thumbs.db"))
{
Bitmap newBtmap = (Bitmap)Image.FromFile(flName);
FileInfo fi = new FileInfo(flName);
long l = fi.Length;
if (l > compressSize)
{
newBtmap = resizeImage(newBtmap, 1024,768) ;
newBtmap = saveJpeg(IMAGE_PATH + (SCANNING_NUMBER +
) + ".jpg", newBtmap, IMAGE_QUALITY);
}
else
{
File.Copy(flName, TEMP_IMAGE_PATH + (SCANNING_NUMBER + 1) + ".jpg");
}
if (!bgwLoading.CancellationPending)
{
CommonInformation.SCANNING_NUMBER++;
this.SafeInvoke(d => d.addItemToLvImageContainer(newBtmap));
bgwLoading.ReportProgress((int)Math.Round((double)i / (double)
(totalFiles) * 100));
i++;
}
}
}
}
}
public void addItemToLvImageContainer(Bitmap newBtmap)
{
imageList.Images.Add(newBtmap);
ListViewItem item;
item = new ListViewItem();
item.ImageIndex = SCANNING_NUMBER - 1;
item.Text = SCANNING_NUMBER.ToString();
lvImageContainer.Items.Add(item);
lvImageContainer.Items[item.ImageIndex].Focused = true;
}
To find out the error I have modified the code as follows:
I have commented the two lines
//newBtmap = resizeImage(newBtmap, 1024, 768);
// newBtmap = saveJpeg(IMAGE_PATH + scanning_number + ".jpg", newBtmap, Image_Quality );
and added try-catch as follows:
try
{
Bitmap newBtmap = (Bitmap)Image.FromFile(flName);
File.Copy(flName, CommonInformation.TEMP_IMAGE_PATH +
(CommonInformation.SCANNING_NUMBER + 1) + ".jpg");
if (!bgwLoading.CancellationPending)
{
this.SafeInvoke(d => d.imageList.Images.Add(newBtmap));
ListViewItem item;
item = new ListViewItem();
CommonInformation.SCANNING_NUMBER++;
item.ImageIndex = CommonInformation.SCANNING_NUMBER - 1;
item.Text = CommonInformation.SCANNING_NUMBER.ToString();
this.SafeInvoke(d => d.lvImageContainer.Items.Add(item));
bgwLoading.ReportProgress((int)Math.Round((double)i /
(double)(totalFiles) * 100));
this.safeInvoke(d=>d.addItemImageContainer(newBtmap))
catch (Exception ex)
{
MessageBox.Show( ex.Message);
}
It shows the error message after loading some images as "OutOfMemoryException"
Most probably the following line creates the exception:
Bitmap newBtmap = (Bitmap)Image.FromFile(flName);
But the image files are not corrupted and their file extension is .JPG.
How to get rid of this problem?
I have no answer, but i have some suggestions:
Check .NET framework version on computers with problems
Check, if you have permissions for files you trying to read
Use "try-catch" when you accessing files
And questions:
Is this project written in older version of .NET and migrated/upgraded to .NET 4.0?
Are you using any non-built-in assemblies or external dll's for image processing?
I would like to fill my ListView with do aligned elements, a little icon (either a confirm mark or a cross) and a string which contains the result of a question (Right / Wrong, that's why icon).
daInserire = new ListViewItem();
daInserire.Foreground = new SolidColorBrush(Colors.DarkGreen);
daInserire.Content = "Giusto: "+ straniero.Text + " = " + vocItaliano[current];
daInserire.HorizontalContentAlignment = HorizontalAlignment.Center;
daInserire.FontSize = 18;
//...
listViewConInfo.Items.Add(daInserire);
This works perfectly, I'd like to add before the string, on the same line an image.
Looks like you're using WPF, so you'll need to create a StackPanel for your Content property and add the Image and a Label to that StackPanel.
ListView lV = new listView();
ListViewItem Item = new ListViewItem();
WrapPanel wrap = new WrapPanel();
Image image = new image();
image.Source = <<yourSource>>;
Label label = new Label();
label.Content = "W/E you want";
wrap.Children.Add(image);
wrap.Children.Add(label);
Item.Content = wrap;
lV.Items.Add(Item);