|
According to Documentation[^]
"You must keep the stream open for the lifetime of the Image." so should not the second snippet throw an exception?
|
|
|
|
|
Hi Giorgi,
Thanks. I missed that line in the documentation, and no it has never thrown me an Exception; AFAIK once the pixels are loaded, file (and now also the stream) access is needed only when extra information is asked for, (e.g.the JPEG tags), which I don't ask for unless I use Image.FromFile().
Theoretically I now must change my standard reply to always create a copy of the first image, then dispose of it. Grr.
|
|
|
|
|
Windows probably has the bitmap locked if you are saving the file over itself.
If you are trying to save the image over itself. First, create a copy of the image and dispose of the original bitmap. Then apply the title to the copy and save it over the original image. Once disposed, it should not give you any problems.
you can use the Bitmap(Bitmap) constructor in order to make a copy.-Bryan
My latest programming adventure was coding the multimedia features for the Rip Ride Rockit coaster at Universal Studios Florida. I love my job.
|
|
|
|
|
Hi,
Thanks for the advice.
I have checked the amount of space on my HDD and i have 255 GB free. I am trying to save the images back to a folder which is located in "Pictures" folder.
I tried to make a copy of the image but it still throws an exception. My write method writes the title to the global image after i have created the image.
I am using Filestream as advised. I have wrapped the whole block of code when using the "using" directive.
I also dispose the global image after i have made a copy of it. I used the clone method and then use the cloned image to be saved. But i still get the same error message.
Any thoughts?
Here is a segment of the code:
else if(txtBoxOut.Text != "")
{
string destFolder = txtBoxOut.text
foreach(string filePath in filePaths)
{
using(FileStream fileStream = File.OpenRead(filePath))
{
this.bmp = Image.FromStream(fileStream);
string fileName = Path.GetFileName(filePath);
try
{
Image newImage = (Image)this.bmp.Clone();
this.bmp.Dispose();
if(destFolder.EndsWith("\\")
{
this.newImage.Save(destFolder+fileName+ImageFormat.Jpeg);
}
else
{
this.newImage.Save(destFolder+"\\"+fileName+ImageFormat.Jpeg);
}
}
catch(Exception e)
{
Console.WriteLine(e.message.ToString());
}
}
}
}
|
|
|
|
|
Hi,
In this bit of code you still have the stream open because you are doing your bitmap operations inside your using. Windows may still have hold of the bitmap. Copy the bitmap inside the using and do the other stuff outside of the using. See if that works. something like this...
using(FileStream fileStream = File.OpenRead(filePath))
{
this.bmp = Image.FromStream(fileStream);
string fileName = Path.GetFileName(filePath);
Image newImage = (Image)this.bmp.Clone();
this.bmp.Dispose();
}
if(destFolder.EndsWith("\\"))
.
.
. -Bryan
My latest programming adventure was coding the multimedia features for the Rip Ride Rockit coaster at Universal Studios Florida. I love my job.
|
|
|
|
|
Hi,
I tried to do the above but an exception thrown when i try to write the title. The newImage is global in my case because the title has to be written this way...
I try to check outside the using block if the contents in the textbox has been changed and if it has i call the ApplyTitle method which is meant to write the title. But now it throws the exception when i try to write the title.
The exception is also thrown again when i try to save the cloned image
|
|
|
|
|
when you want to create a new file, unrelated to existing, already open, files all stuff about locked files, file streams, etc is irrelevant. What is relevant though is:
destFolder+fileName+ImageFormat.Jpeg
is non-sense. Store that in a string variable and look at its value.
|
|
|
|
|
Yes, Luc is right... Wow, i don't believe i didn't see that.
-Bryan
My latest programming adventure was coding the multimedia features for the Rip Ride Rockit coaster at Universal Studios Florida. I love my job.
|
|
|
|
|
Hi,
Thanks for your assistance,
Just looked at this post after i posted my previous post.
Duh me, I can see that its writing jpeg twice. I have changed this so its like C:\.......\image.jpg
But
I tried to save the file and I still get the same exception. By the way I have done what Bryan advised me to do.
I am going to revert my changes i have made apart from the change i have made to the save method.
*Update*
I have reverted the changes and i still get the same exception. I have checked my ApplyTitle method and all it is doing is setting the user specified value of the title propertyitem of the image.
Any further advice would be much appreciated.
Thanksmodified on Friday, March 5, 2010 7:21 PM
|
|
|
|
|
Eagle32 wrote: Console.WriteLine(e.message.ToString());
No
Not like that. Message is already a string, calling ToString() on it doesn't do anything but waste CPU cycles. The net result is still a single line of text.
What you should do is e.ToString() that will provide all available information. Do it now, and tell us what it gives you.
|
|
|
|
|
Hi,
Thanks, Here is what i get:
System.Runtime.InteropServices.ExternalException was caught
Message="A generic error occurred in GDI+."
Source="System.Drawing"
ErrorCode=-2147467259
StackTrace:
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at System.Drawing.Image.Save(String filename)
at ZooSystem.ImageViewer.ApplyChanges() in E:\ZooSystem\ImageViewer.cs:line 520
InnerException:
I suspect it is something to do with folder permissions but i have checked the folder and file permissions.
I am saving the animal pictures back to its original location which is C:\Users\<username>\Pictures\Animals
Now in the code it looks like this C:\\Users\\<username>\\Pictures\\Animals.
|
|
|
|
|
Just an odd question. What happens when you try to save the image in the same folder but a different name?
Also, what happens if you go to this folder in Windows explorer and try to create a file? like a new text document or the like.
Does UAC gripe at you or something?-Bryan
My latest programming adventure was coding the multimedia features for the Rip Ride Rockit coaster at Universal Studios Florida. I love my job.
|
|
|
|
|
Apologies for late reply, it appears to be working.
Thanks for the help.
|
|
|
|
|
Your welcome. -Bryan
My latest programming adventure was coding the multimedia features for the Rip Ride Rockit coaster at Universal Studios Florida. I love my job.
|
|
|
|
|
I have a button on a form that triggers a pop up (This is a Windows Form App, not an ASP.Net App) to collect additional data based on what the related combobox value was when the button was pressed. This form can have anywhere from 2 to 10 inputs (Radio Buttons, Combo Boxes) on the screen.
The issue is this: I don't want to make 15 forms to accommodate all of the possibilities, so I decided (Or am still deciding) to make a dynamic form that accepts the combobox value as an argument. So parent form has combobox A and sends that value to child form on button press.
First of all I would like to know what you think of the idea of having a dynamic form vs. 15 forms.
Secondly, on the dynamic form idea I decided to create a form with all of the possible elements (5 groupboxes with radio buttons, 5 comboboxes, 1 multiline textbox and 1 save button) and then resize and show / hide / position the controls as necessary based on the input. I can handle this well enough, though it seems laborious, but I am having an issue with dynamically loading information into my comboboxes, see this code:
switch (theId)
{
case 24:
this.Size = new System.Drawing.Size(348, 619);
foreach (Control ctrl in Controls)
{
ctrl.Visible = true;
}
break;
case 25:
string[] myControls = new string[4] { "groupBox1", "label1", "comboBox1", "btnSave" };
foreach (Control ctrl in Controls)
{
if (Array.IndexOf(myControls, ctrl.Name) == -1)
{
ctrl.Visible = false;
}
else
{
ctrl.Visible = true;
switch (Array.IndexOf(myControls, ctrl.Name))
{
case 0:
ctrl.Text = "Blah";
break;
case 1:
ctrl.Text = "Foo";
break;
case 2:
if (ctrl is ComboBox)
{
My breakdown is here at the end, the Control ctrl won't accept the Combobox.Items.Add, so how do I add items to it? And is this whole approach just not right?
|
|
|
|
|
Well, you didn't show the line where you are calling ComboBox.Items.Add
But have you tried this?
try
{
(ctrl as ComboBox).Items.Add(whatevertoaddhere);
}
catch(Exception ex)
{
}
or something of the like.My latest programming adventure was coding the multimedia features for the Rip Ride Rockit coaster at Universal Studios Florida. I love my job.
|
|
|
|
|
It's hard to tell where your 15 choices come from, but I recently had a similar problem. If you're choices are based on a reasonably designed class or classes, you should look at using reflection to dynamically add the controls you need:
foreach (Type mytype in Assembly.GetEntryAssembly().GetTypes())
{
if (type_matches_criteria)
{
(create new control)
(adjust control details and location)
Controls.Add(new_control)
}
}
Then to use your controls:
foreach (Control ctrl in (from Control c in Controls where c (meets criteria) select c))
{
if (ctrl.Checked)
{
ctrl.Text = "Blah";
}
}
|
|
|
|
|
Is it possible to launch an external application, say Excel for example, but then "dock" the launched application into my application (as if it were a component)? This why the user could view my portion in one side of a "split" window, and access the launched application in the other side of the split window - my customer prefers this over just resizing two applications and placing them side-by-side, plus his application is required to run in full screen mode, so this isn't possible, and alt-tabbing is a less preferred alternative.
|
|
|
|
|
|
Thanks
|
|
|
|
|
I've created a DataGridView with one column of type DataGridViewTextBoxCell. I'd like to disable the right click context menu that appears when the cell is in edit mode. I've seen examples with textboxes where you set the control's ContextMenu property to a new ContextMenu object, but this doesn't seem to work for DataGridViewTextBoxCell objects.
I've tried to do the following:
private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e)
{
DataGridView gv = ((DataGridView)sender);
if (gv.Rows[e.RowIndex].Cells[e.ColumnIndex].ContextMenuStrip == null)
{
gv.Rows[e.RowIndex].Cells[e.ColumnIndex].ContextMenuStrip = new ContextMenuStrip();
}
}
Thinking it might do the same, but when the cell enters edit mode, it displace the default (for lack of a better term) context menu.
Any help/incite is much appreciated. Thanks.
|
|
|
|
|
Hello!
I am looking for a way to have one instance of my program talk to another.
I only want one instance of the program open at a time, so I’ve set up a mutex to restrict access. My program also allows the user to launch different froms in the program by using command line arguments. If the user launches a new instance of the program with command line parameters I would like the second instance (the once just launched) to pass the arguments to the first instance, then the second instance will close.
I was wondering if I could store a pointer to the first instance of my program somewhere that could be retrieved by the second? Maybe from the Mutex or something similar, but I haven’t had any luck finding a way to do this.
Thank you all in advance!
|
|
|
|
|
You could always have a socket open and listening too, but I'd probably use the named pipes in the above link.
|
|
|
|
|
Thank you both for your answers! My users are on systems that only have .NET 2.0 and I don’t have the ability to ensure all users have .NET 3.5.
I will use your idea of having a socket open since I already have a server listening (which is why I didn’t want a second instance open). That is a brilliant idea and works perfectly for what I’m doing!
Thank you both again!
|
|
|
|
|
I've been trying to find a way to get the link at a certain point in a LinkLabel.
I've done it with items in a ListView using
Point p = lv.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y));
ListViewItem lvi = lv.GetItemAt(p.X, p.Y);
I've been able to find the LinkLabel equivalent, PointInLink(), but it's a protected method and I don't know how to access it.
I've been googling for a couple days now and I just can't find an example I can wrap my head around. I was hoping someone could point me in the right direction.
Thanks in advance.
PointInLink() found at http://msdn.microsoft.com/en-us/library/system.windows.forms.linklabel.pointinlink(VS.71).aspx
I'm using VS2008, .NET 3.5.
Edit --------------
Another solution I've been looking at is checking the state of my links, like
foreach (LinkLabel.Link lnk in ll.Links)
{
if (lnk.*State* == LinkState.Hover)
// do something
}
This would work for me, except I cannot find a way to get the link's current state. The lnk variable (used in the loop) does not have a definition for it.modified on Friday, March 5, 2010 3:58 PM
|
|
|
|