Showing processed images from an IP camera - wpf

I have an IP-camera that serves images. These images are then processed via EmguCV and then I want to display the processed images.
To show the images, I use this code:
Window1(){
...
this.Dispatcher.Hooks.DispatcherInactive
+= new EventHandler(Hooks_DispatcherInactive);
}
Hooks_DispatcherInactive(...)
{
Next()
}
Next() the calls calls the image processing methods and (should) display the image:
MatchResult? result = survey.Step();
if (result.HasValue)
{
Bitmap bit = result.Value.image.Bitmap;
ImageSource src = ConvertBitmap(bit);
show.Source = src;
...
}
This works fine when I hook up a normal 30fps webcam. But, the IPCam's images take over a second to get here, also when I access them via a browser. So, in the mean time, WPF shows nothing, not even the previous image that was processed.
How can I get WPF to at least show the previous image?

You can copy the image's buffer into a new BitmapSource image of the same format (PixelFormat, Height, Width, stride) using Create (from Array) or Create (from IntPtr) and display that BitmapSource in WPF's Image control,
or you can use DirectX to do that faster (for 30fps (and 1fps) the BitmapSource approach should do).
Also, consider NOT using events in the view, instead use bindings and commands.

Related

PDFSharp TextFormatter.DrawString() with fractional font sizes in PDFSharp gives shortened lines

I'm using WPF, and I have a RichTextBox in my user interface, which I convert to a PDF file. I take the RichTextBox.Document FlowDocument from the RichTextBox and translate it to a PdfSharp.Pdf.PdfPage.
This has been working pretty good (after finding some help for wordwrap on SO), but I found that I need to scale the PDF, so after I get the font from the FlowDoc, I multiply it by a scale factor, in my case 0.88.
This appeared to work great, but on closer inspection, I found that a few lines were terminating early.
// these lines use font info from the FlowDoc. To simplify, I've
// hard-coded the font size.
// this works fine:
var thisRunXFont = new XFont(thisRun.FontFamily.Source, 14, xRunFontStyle);
// this causes problems:
var thisRunXFont = new XFont(thisRun.FontFamily.Source, 12.32, xRunFontStyle);
Has anyone else seen this kind of trouble? I do go on to use MeasureString() to get the enclosing paragraph -- but forcing the rectangle to be wider does not change the behavior.

Esri Silverlight control Pan/Zoom from code

I have trouble getting Map behave properly when calling ZoomToResolution and PanTo
I need to be able to Zoom into specific coordinate and center map.
The only way I got it working is by removing animations:
this.MapControl.ZoomDuration = new TimeSpan(0);
this.MapControl.PanDuration = new TimeSpan(0);
Otherwise if I make call like this:
control.MapControl.ZoomToResolution(ZoomLevel);
control.MapControl.PanTo(MapPoint());
It does one or another (i.e. pan or zoom, but not both). If (after animation) I call this code second time (map already zoomed or panned to needed position/level) - it does second part.
Tried this:
control.MapControl.ZoomToResolution(ZoomLevel, MapPoint());
Same issue, internally it calls above commands
So, my only workaround right now is to set Zoom/Pan duration to 0. And it makes for bad UX when using mouse.
I also tried something like this:
this.MapControl.ZoomDuration = new TimeSpan(0);
this.MapControl.PanDuration = new TimeSpan(0);
control.MapControl.ZoomToResolution(ZoomLevel);
control.MapControl.PanTo(MapPoint());
this.MapControl.ZoomDuration = new TimeSpan(750);
this.MapControl.PanDuration = new TimeSpan(750);
Which seems to be working, but then mouse interaction becomes "crazy". Mouse scroll will make map jump and zoom to random places.
Is there known solution?
The problem is the second operation replaces the previous one. You would have to wait for one to complete before starting the next one. But that probably doesn't give the effect you want.
Instead zoom to an extent, and you'll get the desired behavior. If you don't have the extent but only center and resolution, you can create one using the following:
var zoomToExtent = new Envelope(point.X - resolution * MapControl.ActualWidth/2, point.Y, point.X + resolution * MapControl.ActualWidth/2, point.Y);
Btw it's a little confusing in your code that you call your resolution "ZoomLevel". I assume this is a map resolution, and not a level number right? The esri map control doesn't deal with service-specific levels, but is agnostic to the data's levels and uses a more generic "units per pixels" resolution value.

Load an Image in Multiple movie clips using as3

I am really curious of asking a particular question to everyone of you. I am creating an Application in flash that is lot similar to this Application Zazzle Case Cover
I am almost ready with what i was supposed to do and How i have to do. But, still i am ain't a very big Tech_geek to handle all these . I list out some of the things which i could`nt achieve. Kindly help me if possible.
I know that inorder to load unlimited number of images in a Movie Clip, we need Array. But to go with it, I am not sure of framing it properly.
I have Merged certain codings from internet and encoded it to act as the Application in that Site for a Single image in a Single view, but when i try to add child or make it display the same image in all other views i can't frame the coding. It is not behaving properly .
Last but not the Least, I am confused of displaying the Bitmap data in as3... I wanted to show the Uploaded Panel Image in the below thmbnail area but i am not so sure of it.
The Questionnaire format of the Above problems are
How to upload unlimited number of images in a Movie Clip using Array ?
Is it is possible to Display the same image in two Movie Clips simultaneously using addChild ?
I had lots of blah and blah but this area plays the 2nd Question and even Answer for it. But i am ain't sure revealing the Answer.
function onMovieClipLoaderComplete(event:Event):void
{
// Hide progress bar
progressBar.visible=false;
var loadedContent:DisplayObject=event.target.content;
var loader:Loader=event.target.loader as Loader;
loadedContent.x=-37.625;
loadedContent.y=-37.625;
loadedContent.width=75.25;
loadedContent.height=75.25;
trace("loadedContent.width="+loadedContent.x);
trace("loadedContent.height="+loadedContent.y);
mcOnStage=true;
con1.container.addChild(loader);
clears.addEventListener(MouseEvent.CLICK, removeMC);
function removeMC(MouseEvent):void {
trace("Its Removed");
if (mcOnStage )
{
con1.container.removeChild(loader);
con1.textcontainer.removeChild(txt);
mcOnStage=false;
}
}
}
"con1.container.addChild(loader);"
Can i add "con1.container2.addChild(loader);" for the same loaded image.
How to Clone a Movieclip's Bitmap data and Display it in another area or Movieclip ???
Guide me if possible...
I have included the SWF file along with this Question...
https://docs.google.com/file/d/0B5jnHM1zpP4MOHRCeWFqX05sSTA/edit?usp=sharing
Can Someone check the first Site and gimme little notes of how can i bring all those modules in this flash as3 based application.
Here's how you would display the same image twice, with reference to the code you included in your post:
//here's your code
var loadedContent:DisplayObject=event.target.content as DisplayObject;
//create bitmap data instance same size and as the loaded content
var transparent:Boolean = true;
var fillColor:uint = 0xFFFFFFFF;
var bitmapData:BitmapData = new BitmapData(loadedContent.width, loadedContent.height, transparent, fillColor);
//draw the loaded content into the bitmap data
bitmapData.draw( loadedContent );
//create new bitmap
var bitmap:Bitmap = new Bitmap( bitmapData);
//add the loaded content
con1.container.addChild(loader);
//add your 'cloned' content
con1.container2.addChild( bitmap );

FrameBuffer to file inside libgdx or OpenGL

I am trying to take screenshots in the most efficient way. I thing using a FrameBuffer is the most efficient way of taking screenshots because i can process the data in different thread than rendering thread.
How can i get the information from FrameBUffer and transfer it to a file?
FrameBuffer m_fbo;
render(){
m_fbo = new FrameBuffer(Format.RGB565, (int)(w * m_fboScaler), (int)(h * m_fboScaler), false);
m_fboRegion = new TextureRegion(m_fbo.getColorBufferTexture());
m_fboRegion.flip(false, true);
m_fbo.begin();
...rendering...
m_fbo.end();
writeTextureRegionToFile(); - i need some lines of code for the implementation of this method
}
The FrameBuffer contents reside in memory managed by OpenGL, so you will (as far as I understand things) still need to fetch those bytes using OpenGL APIs on the render thread. Specifically, you want the ScreenUtils class
to get a byte[] containing the RGBA8888 contents of your FrameBuffer.
Once you get the raw bytes, you can do any compression/conversion/output on a different thread, of course. There is a forum post that has a quick and dirty PNG writer. The Libgdx-specific (?) CIM format is also an option (see the PixmapIO class), but you'll have to convert the bytes into a Pixmap first.

How to generate and print large XPS documents in WPF?

I would like to generate (and then print or save) big XPS documents (>400 pages) from my WPF application. We have some large amount of in-memory data that needs to be written to XPS.
How can this be done without getting an OutOfMemoryException? Is there a way I can write the document in chunks? How is this usually done? Should I not be using XPS for large files in the first place?
The root cause of the OutOfMemoryException seems to be the creation of the huge FlowDocument. I am creating the full FlowDocument and then sending it to the XPS document writer. Is this the wrong approach?
How do you do it? You didn't show any code.
I use an XpsDocumentWriter to write in chunks, like this:
FlowDocument flowDocument = . .. ..;
// write the XPS document
using (XpsDocument doc = new XpsDocument(fileName, FileAccess.ReadWrite))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
DocumentPaginator paginator = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator;
// Change the PageSize and PagePadding for the document
// to match the CanvasSize for the printer device.
paginator.PageSize = new Size(816, 1056);
copy.PagePadding = new Thickness(72);
copy.ColumnWidth = double.PositiveInfinity;
writer.Write(paginator);
}
Does this not work for you?
Speaking from perfect ignorance of the specific system involved, might I suggest using the Wolf Fence in Alaska debugging technique to identify the source of the problem? I'm suggesting this because other responders are not reporting the same problem you are experiencing. When working with easy-to-reproduce bugs Wolf Fence is dead simple to do (it doesn't work so well with race conditions and the like).
Pick a midpoint in your input data and try to generate your output document from only that data, no more.
If it succeeds, pick a point about 75% into the input and try again, otherwise pick a point at about 25% of the way into the input and try again.
Lather, rinse, repeat, each time narrowing the window to where the works/fails line is.
You may find that you fairly quickly identify one specific page -- or perhaps one specific object on that page -- that is "funny." Note: you only have to do this log2(N) times, or in this case 9 times given the 400 pages you mention.
Now you probably have something you can attack directly. Good luck.
You cannot use a single FlowDocument for generating large documents because you will run out of memory. However if it is possible to generate your output as a sequence of FlowDocument or as an extremely tall ItemsControl, it is possible.
I've found the easiest way to do this is to subclass DocumentPaginator and pass an instance of my subclass to XpsDocumentWriter.Write:
var document = new XpsDocument(...);
var writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
writer.Write(new WidgetPaginator { Widget = widgetBeingPrinted, PageSize = ... });
The WidgetPaginator class itself is quite simple:
class WidgetPaginator : DocumentPaginator, IDocumentPaginatorSource
{
Size _pageSize;
public Widget Widget { get; set; }
public override Size PageSize { get { return _pageSize; } set { _pageSize = value; } }
public override bool IsPageCountValid { return true; }
public override IDocumentPaginatorSource Source { return this; }
public override DocumentPaginator DocumentPaginator { return this; }
public override int PageCount
{
get
{
return ...; // Compute page count
}
}
public override DocumentPage GetPaget(int pageNumber)
{
var visual = ...; // Compute page visual
Rect box = new Rect(0,0,_pageSize.With, _pageSize.Height);
return new DocumentPage(visual, _pageSize, box, box);
}
Of course you still have to write the code that actually creates the pages.
If you want to use a series of FlowDocuments to create your document
If you're using a sequence of FlowDocuments to lay out your document one section at a time instead of all at once, your custom paginator can work in two passes:
The first pass occurs as the paginator is constructed. It creates a FlowDocument for each section, then gets a DocumentPaginator to retrieve the number of pages. Each section's FlowDocument is discarded after the pages are counted.
The second pass occurs during actual document output: If the number passed to GetPage() is in the most recent FlowDocument created, GetPage() simply calls that document's paginator to get the appropriate page. Otherwise it discards that FlowDocument and creates a FlowDocument for the new section, gets its paginator, then calls GetPage() on the paginator.
This strategy allows you to continue to use FlowDocuments as you have been, as long as you can break the data into "sections" each with its own document. Your custom paginator then effectively treats all the individual FlowDocuments as one big document. This is similar to Word's "Master Document" feature.
If you can render your data as a sequence of vertically-stacked visuals
In this case, the same technique can be used. During the first pass, all visuals are generated in order and measured to see how many will fit on a page. A data structure is built to indicate which range of visuals (by index or whatever) are found on a given page. During this process each time a page fills up, the next visual is placed on a new page. Headers and footers would be handled in the obvious way.
During the actual document generation, the GetPage() method is implemented to regenerate the visuals previously decided to be on a given page and combine them using a vertical DockPanel or other panel of your choice.
I've found this technique more flexible in the long run because you don't have to deal with the limitations of FlowDocument.
I can confirm that XPS does not throw out-of-memory on long documents. Both in theory (because operations on XPS are page-based, it doesn't try to load whole document in memory), and in practice (I use XPS-based reporting, and seen run-away error messages add up to many thousands of pages).
Could it be that the problem is in a single particularly large page? A huge image, for example? Large page with high DPI resolution? If single object in document is too big to be allocated at once, it will lead to out-of-memory exception.
Have you used sos to find out what is using up all the memory?
It could be that managed or unmanaged objects are being created during the production of your document, and they're not being released until the document is finished (or not at all).
Tracking down managed memory leaks by Rico Mariani could be of help.
like you say: probably the in-memory FixedDocument is consuming too much memory.
Maybe an approach in which you write out the XPS pages each individually (and make sure the FixedDocument gets released each time), and then use a merger afterwards could prove fruitful.
Are you able to write each page separately?
Nick.
ps. Feel free to concact me directly (info#nixps.com); we do a lot of XPS stuff at NiXPS, and I'm very interested in helping you getting this issue resolved.

Resources