Memory handling imagelist, out of memory - c#

I've run into a real headache here.
I have a small program, which displays some images stored on disk. 8 images are displayed in a listview at a time, but when the images are large enough, the memory use (according to the task manager) reaches more than 1300mb! I suspect that there are some images or something which aren't deallocated, but I seem to be unable to pinpoint exactly where. I have tried both disposing all images in listview.largeimagelist.images, tried Clear()'ing the imagelist, but it doesn't make a difference at all.
Here is the current code:
private void btnLoadNewImages_Click(object sender, EventArgs e)
{
int k = lsvImgResult.Items.Count;
for (k = lsvImgResult.Items.Count; k >= 1; k--)
{
Seen.Push((MyFile)lsvImgResult.Items[k - 1].Tag);
imageList.Images.Clear();
}
int i = 0;
lsvImgResult.Items.Clear();
DisplayedImages.Clear();
imageList.Images.Clear();
imageList.ImageSize = new Size(100, 100);
imageList.ColorDepth = ColorDepth.Depth32Bit;
int HowMany = 0;
if (UnSeen.Count >= 8)
{
HowMany = 8;
}
else
{
HowMany = UnSeen.Count;
}
for (i = 1; i <= HowMany; i++)
{
MyFile CurFile = UnSeen.Pop();
Image j = Image.FromFile(CurFile.Filename);
DisplayedImages.Enqueue(CurFile);
imageList.Images.Add(j);
}
lsvImgResult.LargeImageList = imageList;
for (int j = 0; j < imageList.Images.Count; j++)
{
ListViewItem lstItem = new ListViewItem();
lstItem.ImageIndex = j;
lstItem.Tag = DisplayedImages.Dequeue();
lstItem.ToolTipText = ((MyFile)lstItem.Tag).Filename;
lsvImgResult.Items.Add(lstItem);
}
tabImagesLeft.Text = "Images left: " + UnSeen.Count;
}

Related

Hiding an array picturebox c#

This generates a picturebox
PictureBox[][] picturebox;
public void loadPictureBox()
{
string path = #"../../Images/Catelogue/"; //set pathing
string[] list = Directory.GetFiles(path, "*.jpg");
//pictureboxCatelogue = new PictureBox[list.Length];
//pictureboxCosplay = new PictureBox[list.Length];
picturebox = new PictureBox[4][];
for (int i = 0; i < 4; i++)
{
picturebox[i] = new PictureBox[list.Length];
int y = 85, temp = 220, run = 0;
for (int index = 13; index < list.Length; index++) // loads all pictures and create pictureboxes
{
picturebox[i][index] = new PictureBox();
picturebox[i][index].Image = Image.FromFile(path + index + ".jpg");
this.Controls.Add(picturebox[i][index]);
temp = temp + 200;
if (index % 4 == 0)
{
if (run != 0)
y = y + 200;
run++;
temp = 220;
}
picturebox[i][index].Location = new Point(temp, y);
picturebox[i][index].Size = new Size(180, 180);
picturebox[i][index].Name = Convert.ToString(index);
picturebox[i][index].SizeMode = PictureBoxSizeMode.Zoom;
picturebox[i][index].BackColor = Color.FromArgb(35, 35, 35);
picturebox[i][index].Click += new System.EventHandler(PictureBox_Click);
}
}
}
I'm trying to hide a jagged array which is a picturebox in winsform c#, but i keep getting an error, is hiding a jagged array possible? This is the code that i'm having trouble with.
for (int i = 0; i < picturebox.Length; i++)
{
picturebox[0][i].Hide();
}
This is the error i get
ERROR : A first chance exception of type 'System.NullReferenceException' occurred in APPD Assignment 2.exe (Additional information: Object reference not set to an instance of an object.)
Aren't you using the wrong length here?
for (int i = 0; i < picturebox.Length; i++)
Should be
for (int i = 0; i < picturebox[0].Length; i++)
When you load the pictureboxes, you're only starting at index 13, so you either need to start the hide loop at 13, or check for null.
for (int i = 13; i < picturebox[0].Length; i++)
{ ... }
or
for (int i = 0; i < picturebox[0].Length; i++)
{
if (picturebox[0][i] != null)
{
picturebox[0][i].Hide();
}
}

Listbox not removing values in c# GUI

The user basically enters a number of hex values into a textbox separated by commas eg. AA,1B,FF. These are then displayed in a listbox box. if the number of hex values in the textbox exceeds the size to transfer defined by the user, the listbox only displays the this number of values or if the size to transfer is bigger that adds zero values to the listbox.
this works fine until you enter a value with a zero in front of it such as AA,BB,CC,DD,EE,0F, if sizeToTransfer = 2, the listbox should display 0xAA and 0xBB. but instead it only removes the 0F value?
I'm pretty new to programming so it may be something obvious I'm missing any help would be appreciated.
private void WriteSPI1_Click(object sender, EventArgs e)
{
string hexstring = textbox1.Text;
HexValues.Items.Clear();
string[] hexarray = hexstring.Split((",\r\n".ToCharArray()), StringSplitOptions.RemoveEmptyEntries);
byte[] hexbytes = new byte[hexarray.Length];
uint num = Convert.ToUInt32(hexarray.Length);
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
if (hexarray.Length > sizeToTransfer)
{
diff = num - sizeToTransfer;
for (i = 0; i < diff+1; i++)
{
HexValues.Items.Remove("0x" + x);
}
}
else
{
diff = sizeToTransfer - num;
for (i = 0; i < diff; i++)
{
HexValues.Items.Add("0x00");
}
}
}
CHANGE
for (int j = 0; j < sizeToTransfer; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
WITH
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
and remove the if stantment that follow

Image Manipulation using Average Kernel

Ive been working on a code that takes an image, turns it into grayscale, and then does image manipulation depending on which button is pressed. When a button is pressed (ex. Average 3x3, Prewitt 5x5), it calls a 2D Multiplication function, which loops over the grayscale image, while looping over the kernel, adding all the values in the matrix. If any value is over 255, it sets it to 255. Then using the SetPixel on a temporary bitmap variable, which is finally put into the picturebox. When i run the program, I select an image and it shows it (as grayscale), but after choosing one of the filters, the program freezes for around 30 seconds, and then nothing changes, no filter is applied. Ive tried debugging and i cant seem to locate what the problem is!
EDIT: The initial question has been solved( I had to refresh the picturebox for the new image to show properly.
But i am facing another problem here with regards to the prewitt kernel.
i get this error
"Additional information: Value of '-6' is not valid for 'red'. 'red' should be greater than or equal to 0 and less than or equal to 255."
And i am not sure what to change in my code to fix this.
Initializing:
public partial class Form1 : Form
{
private Image img;
Bitmap grayscaleimage;
double[][] AVGKernel = new double[11][];
double[][] PrewittKernel = new double[11][];
int[] AVGKernal1DH = new int[11];
int[] AVGKernal1DV = new int[11];
Bitmap tempBitmap;
public Form1()
{
InitializeComponent();
for (int i = 0; i < 11; i++)
{
AVGKernel[i] = new double[11];
PrewittKernel[i] = new double[11];
for (int j = 0; j < 11; j++)
{
AVGKernel[i][j] = 0;
PrewittKernel[i][j] = 0;
AVGKernal1DH[j] = 0;
AVGKernal1DV[j] = 0;
}
}
}
The open button and turning the picture into grayscale:
private void OpenImageButton(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
this.img = Image.FromFile(openFileDialog.FileName);
grayscaleimage = new Bitmap(img);
int rgb;
Color c;
for (int y = 0; y < grayscaleimage.Height; y++)
for (int x = 0; x < grayscaleimage.Width; x++)
{
c = grayscaleimage.GetPixel(x, y);
rgb = (int)((c.R + c.G + c.B) / 3);
grayscaleimage.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb));
}
this.pictureBox1.BackgroundImage = grayscaleimage;
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
}
}
an example of the many buttons available:
private void button5_Click(object sender, EventArgs e)
{
AVGKernel[0][0] = 1; AVGKernel[0][1] = 1; AVGKernel[0][2] = 1; AVGKernel[0][3] = 1; AVGKernel[0][4] = 1;
AVGKernel[1][0] = 1; AVGKernel[1][1] = 1; AVGKernel[1][2] = 1; AVGKernel[1][3] = 1; AVGKernel[1][4] = 1;
AVGKernel[2][0] = 1; AVGKernel[2][1] = 1; AVGKernel[2][2] = 1; AVGKernel[2][3] = 1; AVGKernel[2][4] = 1;
AVGKernel[3][0] = 1; AVGKernel[3][1] = 1; AVGKernel[3][2] = 1; AVGKernel[3][3] = 1; AVGKernel[3][4] = 1;
AVGKernel[4][0] = 1; AVGKernel[4][1] = 1; AVGKernel[4][2] = 1; AVGKernel[4][3] = 1; AVGKernel[4][4] = 1;
kernal2DMultiplication(AVGKernel, 5);
this.pictureBox1.BackgroundImage = tempBitmap;
}
Prewitt 5x5 kernel
private void button13_Click(object sender, EventArgs e)
{
PrewittKernel[0][0] = 2; PrewittKernel[0][1] = 1; PrewittKernel[0][2] = 0; PrewittKernel[0][3] = -1; PrewittKernel[0][4] = -2;
PrewittKernel[1][0] = 2; PrewittKernel[1][1] = 1; PrewittKernel[1][2] = 0; PrewittKernel[1][3] = -1; PrewittKernel[1][4] = -2;
PrewittKernel[2][0] = 2; PrewittKernel[2][1] = 1; PrewittKernel[2][2] = 0; PrewittKernel[2][3] = -1; PrewittKernel[2][4] = -2;
PrewittKernel[3][0] = 2; PrewittKernel[3][1] = 1; PrewittKernel[3][2] = 0; PrewittKernel[3][3] = -1; PrewittKernel[3][4] = -2;
PrewittKernel[4][0] = 2; PrewittKernel[4][1] = 1; PrewittKernel[4][2] = 0; PrewittKernel[4][3] = -1; PrewittKernel[4][4] = -2;
kernal2DMultiplication(PrewittKernel, 5);
this.pictureBox1.BackgroundImage = tempBitmap;
this.pictureBox1.Refresh();
}
and finally, the function being called:
private void kernal2DMultiplication(double[][] kernel, int size)
{
tempBitmap = grayscaleimage;
double nrgb = 0;
for (int i = 0; i < grayscaleimage.Width - size / 2; i++)
{
for (int j = 0; j < grayscaleimage.Height - size / 2; j++)
{
if (i >= size / 2 && j >= size / 2)
{
for (int k = 0; k < size; k++)
for (int l = 0; l < size; l++)
nrgb += grayscaleimage.GetPixel(i + k - (size / 2), j + l - (size / 2)).R * kernel[k][l];
nrgb = nrgb / (size * size);
if (nrgb > 255)
nrgb = 255;
tempBitmap.SetPixel(i, j, Color.FromArgb((int)nrgb, (int)nrgb, (int)nrgb));
}
}
}
}
The problem is that you are modifying the BackgroundImage bitmap in-place rather than copying, modifying the copy, and then setting the copy to be the BackgroundImage:
this.pictureBox1.BackgroundImage = grayscaleimage; // initially
tempBitmap = grayscaleimage;
// Make changes to tempBitmap
this.pictureBox1.BackgroundImage = tempBitmap; // actually still the same pointer
The BackgroundImage setter is not forcing a redraw of the control in this case. To force this yourself, call Refresh():
this.pictureBox1.Refresh();
To improver performance, look into replacing multiple calls to SetPixel with a single call to LockBits. See e.g. here.

Removing button from form dynamically on user input

I have a problem. I'm making a web browser in a C# Windows Form, and I've added bookmarks. My problem? Removing them. I can't seem to get good code that will remove the bookmarks! Here's my code:
private void button2_Click_1(object sender, EventArgs e)
{
int removeBookmarkI = 0;
string removeBookmarkName = Microsoft.VisualBasic.Interaction.InputBox("Which bookmark would you like to delete?", "Delete Bookmark", "Google");
for (int i = 0; i < bookmark_names.Length; i++)
{
if (bookmark_names[i] == removeBookmarkName)
{
removeBookmarkI = i;
string[] holdBookmark_names_temp = new string[bookmark_names.Length];
string[] holdBookmark_url_temp = new string[bookmark_names.Length];
for (int j = i; j < bookmark_names.Length - 1; j++)
{
bookmark_names[j] = bookmark_names[j + 1];
bookmark_url[j] = bookmark_url[j + 1];
}
int skipNum = 0;
for (int j = 0; j < bookmark_names.Length - 1; j++)
{
if (bookmark_names[j] == removeBookmarkName)
{
skipNum = 1;
}
holdBookmark_names_temp[j] = bookmark_names[j + skipNum];
holdBookmark_url_temp[j] = bookmark_url[j + skipNum];
}
bookmark_names = new string[bookmark_names.Length - 1];
bookmark_url = new string[bookmark_url.Length - 1];
for (int j = 0; j < bookmark_names.Length; j++)
{
bookmark_names[j] = holdBookmark_names_temp[j];
bookmark_url[j] = holdBookmark_url_temp[j];
}
this.Controls.Remove(buttonsAdded[removeBookmarkI]);
buttonsAdded.Remove(buttonsAdded[bookmark_names.Length - 1]);
this.Controls.Remove(buttonsAdded[bookmark_names.Length - 1]);
System.IO.File.WriteAllLines("C:\\Users\\Public\\IAmAPerson_Web_Explorer\\bookmarks\\bookmark_names.txt", bookmark_names);
System.IO.File.WriteAllLines("C:\\Users\\Public\\IAmAPerson_Web_Explorer\\bookmarks\\bookmarks.txt", bookmark_url);
bookmark_names = new string[bookmark_names.Length - 1];
bookmark_url = new string[bookmark_url.Length - 1];
bookmark_names = System.IO.File.ReadAllLines(#"C:\Users\Public\IAmAPerson_Web_Explorer\bookmarks\bookmark_names.txt");
bookmark_url = System.IO.File.ReadAllLines(#"C:\Users\Public\IAmAPerson_Web_Explorer\bookmarks\bookmarks.txt");
bookmarkButtonSpacing -= 100;
break;
}
if (i == bookmark_names.Length - 1)
{
System.Windows.Forms.MessageBox.Show("You do not have a bookmark named " + removeBookmarkName + "!");
}
}
}
It should prompt for what bookmark you want to delete, remove it, shift all other bookmarks over, and remove it from the web explorer directory files. What's going on? How can I fix this? I'm using a list for my buttons called buttonsAdded. Also, I am aware that this code is probably the worst looking code in C# EVER, but I'm new, and I have yet to learn the best ways to code.

Cannot redraw points which have been set to NULL

I have the following setup:
A TeeChart control with a Colorgrid, and a Points Series added to it:
grid = tChart2.Series[0] as Steema.TeeChart.Styles.ColorGrid;
points = tChart2.Series[1] as Steema.TeeChart.Styles.Points;
To init them, I do:
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.Add(j, rnd.Next(255), i);
}
}
for (int i = 0; i < 20; i++)
{
double x = rnd.Next();
double y = rnd.Next();
points.Add(x, y);
}
tChart2.Refresh();
And then I have a button on my form:
private void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.YValues[j + 128 * i] = rnd.Next(255);
}
}
for (int i = 0; i < 20; i++)
{
points.SetNull(i);
}
for (int i = 0; i < rnd.Next(20); i++)
{
points.XValues[i] = rnd.Next(128);
points.YValues[i] = rnd.Next(128);
}
points.BeginUpdate();
points.EndUpdate();
}
But the points do not get drawn. When I remove the for-loop containing the SetNull() statement, then they do get drawn, but I want to be able to clear the points (or hide the points don't want to be seen) without using the Points.Clear()/Points.Add(x, y) methodology.
I've also tried each of the following, but there's no difference.
points.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
points.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.Ignore;
points.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.Skip;
Does anyone know how to accomplish this?
Ok, the problem is caused when you set null all of points. You must know if you use method SetNull the point color is set transparent to make invisible the point. Therefore, if you want solve your problem you only need reset the colors of points you want visible, doing SetNull again or change the points color manually and combining the operation with TreatNullsStyle set to Ignore. In my opinion, I think the best option is use SetNull again as I do in next code:
public Form1()
{
InitializeComponent();
InitializeChart();
}
Steema.TeeChart.Styles.ColorGrid grid;
Steema.TeeChart.Styles.Points points;
private void InitializeChart()
{
grid = new ColorGrid(tChart1.Chart);
points = new Points(tChart1.Chart);
tChart1.Aspect.View3D = false;
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.Add(i, rnd.Next(255), j);
}
}
for (int i = 0; i < 20; i++)
{
double x = rnd.Next(100);
double y = rnd.Next(100);
points.Add(x, y);
}
}
private void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.YValues[j + 128 * i] = rnd.Next(255);
}
}
for (int i = 0; i < 20; i++)
{
points.SetNull(i);
}
for (int i = 0; i < rnd.Next(20); i++)
{
points.XValues[i] = rnd.Next(128);
points.YValues[i] = rnd.Next(128);
points.SetNull(i, false);
}
points.TreatNulls = TreatNullsStyle.Ignore;
}
Could you tell us if previous code works in correct way for you?
I hope will helps.
Thanks,

Categories