Using `<List>` when dealing with pointers in C# - c#

How can I add an item to a list if that item is essentially a pointer and avoid changing every item in my list to the newest instance of that item?
Here's what I mean:
I am doing image processing, and there is a chance that I will need to deal with images that come in faster than I can process (for a short period of time). After this "burst" of images I will rely on the fact that I can process faster than the average image rate, and will "catch-up" eventually.
So, what I want to do is put my images into a <List> when I acquire them, then if my processing thread isn't busy, I can take an image from that list and hand it over.
My issue is that I am worried that since I am adding the image "Image1" to the list, then filling "Image1" with a new image (during the next image acquisition) I will be replacing the image stored in the list with the new image as well (as the image variable is actually just a pointer).
So, my code looks a little like this:
while (!exitcondition)
{
if(ImageAvailabe())
{
Image1 = AcquireImage();
ImgList.Add(Image1);
}
if(ImgList.Count > 0)
{
ProcessEngine.NewImage(ImgList[0]);
ImgList.RemoveAt(0);
}
}
Given the above, how can I ensure that:
- I don't replace all items in the list every time Image1 is modified.
- I don't need to pre-declare a number of images in order to do this kind of processing.
- I don't create a memory devouring monster.
Any advice is greatly appreciated.

Just reinitialize:
Replace
Image1 = AcquireImage();
with
Image1 = new Image(AcquireImage());
or just say
ImageList.Add(new Image(AcquireImage()));

Your code is correct. None of your above code affects previously added images. The line:
Image1 = AcquireImage();
puts the reference (to an image) returned from AcquireImage into the Image1 reference variable. Then:
ImgList.Add(Image1);
adds that reference to your list. Changing your Image1 reference variable does not affect references already in the list.

Conceptually, your code will be fine. The important element is that AcquireImage() allocates a new instance for each incoming image.
If Image1 were a pointer, you would have a problem - however a C# reference is not a pointer.

If I understand what you're saying correctly, you want to be able to re-use a variable without overwriting its existing data. The good news is that you don't need to change anything. You're partially correct when you say that Image1 is a pointer: it's a reference to whichever image it's pointing to at the time. When you allocate it:
Image1 = AcquireImage();
you're not overwriting the contents of the existing image, but changing the reference so it points to the new image. Assuming AcquireImage is working correctly and returns a new image every time, rather than overwriting the previous one, the above code will discard the existing reference in favour of the new one. However, as you've added it to the list already, a reference to the image is retained somewhere in your code, and so it will not be lost.

Related

Windows Forms Image Resource

Im making a Random Generator with Windows Forms with Images and I use the random pick with resources pictureBox1.Image = Properties.Resources.heart;
Now, the "heart" should get removed from the List, to prevent getting "heart" again.
Here I thought, that I just use int firstCard = randomCard.Next(cards.Count); and I want to use the int firstCard as Properties.Resources.cards[firstCard], because behind Properties.Resources. comes the resource name. But the string doesnt work there, and I dont know how to fix that. Pls help.
Thank you
Pults
Add all your images to a List<Image> - if you have 100 images your list will end up with 100 things
Pick one at random and also remove it. Make the upper bound of random the number of things in the list
//do this once outside the loop that adds images: var r = new Random();
Then the loop that adds images
var x = r.Next(imageList.Count);
var i = inageList[x]; //get the image
imageList.RemoveAt(x); //can't get it again
Note that setting the image of a picture box cannot be done in addition; you'll need multiple picture boxes
Side note, you might find it easier to keep your images in an ImageList (easier to index numerically) - the documentation for it also has some useful/helpful example codes that iteratively draws images into a PictureBox
Also, someone else (maybe doing the same exercise as you :) ) wondered how to get images by string name..
Oh yeah, someone asked the same, didnt find it.
Yea the "ResourceManager.GetObject" is exactly what I needed.
Thanks for the quick response and instant solve!

C# read px from BufferedGraphics?

I currently use the BufferGraphics object if I want to animate my Graphics in C#. The thing is, I would like to know how to access the data which I stored.
I use the buffer to do things like:
bufferContext = BufferedGraphicsManager.Current;
bufferGraphics= bufferContext.Allocate(g, this.DisplayRectangle);
// In some function it would then draw some rectangles or paths etcetera and call
// bufferGraphics.Graphics.FillPath(brush, path);
bufferGraphics.Render(g);
bufferGraphics.Dispose();
Question: But how can I loop through the pixels that I store in BufferGraphics?
Note: I am not allowed to show any source code, however my question should be clear to you if you ever used the bufferGraphics object.

Gettings information about stairsruns and stairs from elements containing such information

Hello I have the following code:
public static void HandleStairs(Document doc)
List<TransitionPoint> ret = new List<TransitionPoint>();
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> stairs = collector.OfCategory(BuiltInCategory.OST_Stairs).ToElements();
foreach (var stair in stairs)
{
var st= stair as Stairs;
if(st!=null)
{
%code that is never executed
}
}
return ret;
}
Now the problem is that no matter what it appears stairs are always null, I heard that another programmer had the same problem.
the stairs variable does receive a number of object with stairlike properties (being named staircase, having risers and platforms ext.) but does not actually appear to accept being cast to a stair. Anybody know how to actually cast this into stairs (or otherwise obtain all stairs in an document?)
Note that stairs is an element with the following properties:
Riser to Tread Connection
Monolithic Material
Apply Nosing Profile
Stringer Material
Text Size
Begin with Riser
Stringer Carriage Height
URL
Open Stringer Offset
Right Stringer
Riser Type
Cost
Left Stringer
Underside of Winder
Stringer Height
Nosing Profile
Manufacturer
Middle Stringers
Keynote
Riser Material
Minimum Tread Depth
Text Font
Monolithic Stairs
Maximum Riser Height
Landing Carriage Height
Break Symbol in Plan
Landing Overlap
Extend Below Base
Nosing Length
Assembly Description
End with Riser
Description
Function
Type Image
Type Comments
Stringer Thickness
Assembly Code
Calculation Rules
Trim Stringers at Top
Model
Tread Thickness
Tread Material
Riser Thickness
I mostly need the stair objects to get the runs assosiated with the stair objects, or actually I need the paths the runs follow.
This can hopefully be used to do the following:
var tesselated = new List<XYZ>();
var stairPath = run.GetStairsPath();
foreach (Curve curve in stairPath)
{
tesselated.AddRange(curve.Tessellate());
}
Because I need the XYZ locations for the positions any stairs attached to the geometry of the building.
First of all, you absolutely have to find out and tell us what kind of element you are talking about. Otherwise, this discussion is completely pointless. One very easy way to determine that is to explore the 'stair-like' element using RevitLookup:
https://github.com/jeremytammik/RevitLookup
If you do not know what RevitLookup is, you should stop absolutely everything else you are doing with the Revit API right away and start off fresh by working through the Revit API getting started material, especially installing and starting to use RevitLookup:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#2
The filtered element collector you show retrieves all elements of the 'Stairs' category. This 'stair-like object' could be a DirectShape, in which case you can assign it the 'Stairs' category. Then it will be retrieved by your filtered element collector above.
Here is an example of a 'stair-like' extruded roof, which is and will always remain a roof, with the 'Roofs' category, and thus can never be identified by your filtered element collector:
http://thebuildingcoder.typepad.com/blog/2014/09/events-again-and-creating-an-extrusion-roof.html#7
Sorry for the confusing answer, but I must say your question is pretty confusing too. Never heard anything like it before. I hope this helps.
What you've done looks reasonable, although as others have pointed out, obviously somehow you are getting back an element which is not a Stair element.
I would suggest - in order to make sure you get back what you want, that you use:
.OfClass(typeof(Stairs))
with the FilteredElementCollector. With this, you can probably drop the WhereElementIsNotElementType() and OfCategory() methods, because it is implicit in the above statement.
This way - whatever you get back should be cast-able.
The as operator returns null if the cast fails, so whatever doc.GetElement(stairId) returns is not of type Stairs or one of its sub-types.
I'm guessing doc is some kind of 'storage' document so you probably need to create a new instance of Stairs and fill it with information you get from whatever doc.GetElement(stairId) returns.

Processing on large bitmaps (up to 3GB)

I'm working on some university project and got stuck with memory issue.
I load a bitmap which takes about 1,5GB on HDD with code below:
Bitmap bmp = new Bitmap(pathToFile);
The issue is that the newly created Bitmap object uses about 3,5GB of RAM which is something I can't understand (that's really BIG wrapper :E). I need to get to the pixel array, and the use of Bitmap class is really helpful (I use LockBits() method later, and process the array byte per byte) but in this case it's total blocker. So here is my question:
Is there any easy way to extract the pixel array without lending additional 2gb?
I'm using c# just to extract the needed array, which is later processed in c++ - maybe I can extract all needed data in c++ (but conversion issue appears here - I'm concentrating on 24bgr format)?
PS: I need to keep the whole bitmap in memory so splitting it into parts is no solution.
PS2: Just to clarify some issues: I know the difference between file extension and file format. The loaded file is uncompressed bitmap 3 bytes per pixel of size ~1.42GB (16k x 32k pixels), so why Bitmap object is more than two times bigger? Any decompressing issues and converting into other format aren't taking place.
Consider using Memory Mapped Files to access your HUGE data :).
An example focused on what you need can be found here: http://visualstudiomagazine.com/articles/2010/06/23/memory-mapped-files.aspx
It's in managed code but you might as well use it from equivalent native code.
Let me know if you need more details.
You can use this solution , Work with bitmaps faster in C#
http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp
Or you can use memory mapped files
http://visualstudiomagazine.com/articles/2010/06/23/memory-mapped-files.aspx
You can stop memory caching.
Instead of
Bitmap bmp = new Bitmap(pathToFile);
Use
var bmp = (Bitmap)Image.FromStream(sourceFileStream, false, false);
see https://stackoverflow.com/a/47424918/887092

How to generate mosaic picture from image file?

I have a source image like left picture and a set of elements like right picture: Source Image And Elements...
..and I need to generate a mosaic picture like this.
But until this moment I have not worked with images, аnd I do not know where I should start.
I worked several years with C#, but you can give examples in other similar languages.
The result image you gave is apparently a ministeck pattern - in 2011 they had a downloadable software that seemed to do what you want. (Which is not available anymore by ministeck directly, but it seems that pfci.de still provides a download).
So, if you're just looking to generate the patterns for ministeck out of a given image, use their software. If you're after an algorithm to achieve something different, this won't help.
EDIT
Ok, if you're after analyzing your image, you need to load it into an object like this:
using(Bitmap b = new Bitmap(yourFileName))
{
MessageBox.Show(string.Format("image size {0} by {1} pixels", b.Width, b.Height));
MessageBox.Show(string.Format("color of pixel (100,100) is {0}", b.GetPixel(100, 100).ToString()));
}
The Bitmap object has several properties and methods that will help you to analyze the image content. Try this to get started with analyzing your image, and don't forget to either dispose your bitmap afterwards or wrap it into a using statement as shown above ...

Categories

Resources