I am developing a barcode scanner.
My application scans a Barcode, than navigates to a second page (with barcodetext on it) and theres a button where i can scan a new barcode when its clicked. So now my problem is that the viewfinderbrush fills the Ram of the windows phone everytime I scan a barcode. If I scan 100 Barcodes, my applikation chrashes because of an out of memory. What can I do to free the memory?
In the zxing demo its the same issue, when I open the scanner and use the back key and open the scanner several times again, the ram is getting higher and higher.
My code for getting the ram:
string storage1 = (DeviceStatus.ApplicationCurrentMemoryUsage / 1000000).ToString() + "MB";
lblram.Text = storage1 ;
I tried everything:
1. Navigationservice.removebackstack
2. Gc.collect (Garbagecollector)
3. disposing the camera
4. use of navigationservice.goback()
Nothing helps
I found out, that the problem is the viewfinderbrush, but i have to inizialize it every time, so thats a problem.
Code:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
string bla1 = (DeviceStatus.ApplicationCurrentMemoryUsage / 1000000).ToString() + "MB";
lblram.Text = bla1;//("Ram: " + Math.Round(((bla1 / 1024)/ 1024), 2));
_matches = new ObservableCollection<string>();
matchesList.ItemsSource = _matches;
// Check to see if the camera is available on the phone.
if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true)
{
_photoCamera = new PhotoCamera(CameraType.Primary);
// Event is fired when the PhotoCamera object has been initialized.
_photoCamera.Initialized += PhotoCameraOnInitialized;
_photoCamera.AutoFocusCompleted += PhotoCameraOnAutoFocusCompleted;
NavigationService.RemoveBackEntry();
viewfinderBrush.SetSource(_photoCamera);
}
else
{
// The camera is not supported on the phone.
MessageBox.Show("A Camera is not available on this phone.");
}
}
What can I do to solve this problem?
Related
Currently I'm developing a cross-platform app using Shared Library that able to take photos. I'm using XLabs.Forms V2.0.5782 package to do this app. I successfully developed this simple app but it only allows me to take one picture at a time.
I messed around with the codes and I managed to take multiple pictures but the problem is, the camera will be closed when I clicked 'Use Photo' and reopen again to take the next photo. What I wanted is, when I clicked 'Use Photo', the camera will reopen on the spot instead of closing and reopen.
Here's the code I did to take multiple pictures but I know it is not the right way to do it. It is in button clicked event.
IDevice device = Resolver.Resolve<IDevice>();
IMediaPicker media = device.MediaPicker;
//More codes here
async void TakePicture(object sender, System.EventArgs e)
{
var options = new CameraMediaStorageOptions()
{
PercentQuality = 50,
DefaultCamera = CameraDevice.Rear,
MaxPixelDimension = 250
};
var cancel = false;
while (!cancel)
{
await media.TakePhotoAsync(options).ContinueWith(t =>
{
if (t.IsFaulted) //If there's an error when taking photos
{
DisplayAlert("Error", "An error occurred when taking photo.\nPlease try again.", "OK");
}
else if (t.IsCanceled) //When the user click 'Cancel'
{
cancel = true;
}
else //When the user click 'Use Photo' - Here's the part where the camera will close and reopen until user click 'Cancel'
{
var img = ImageSource.FromStream(() => t.Result.Source);
picList.Add(img);
}
});
}
if (picList.Count > 0)
{
scrollParent.IsVisible = true;
imageScroll.Children.Clear();
foreach (var pl in picList)
{
var image = new Image()
{
Source = pl,
HeightRequest = 150,
HorizontalOptions = LayoutOptions.Start,
Aspect = Aspect.AspectFit,
Margin = new Thickness()
{
Right = 10
}
};
imageScroll.Children.Add(image);
}
}
}
Is it possible for me to take multiple pictures with XLabs.Forms and is there a proper way? I've search everywhere but found nothing about this. Any help will be much appreciated. Thanks!
Note:
I'm using Visual Studio for Mac Version Preview 9 (7.0 build 2943)
I've only tested on iPhone running iOS 10.2. Have not tested on Android device yet
Here's a gif showing an example of my app. I think this will make you guys have a better understanding of what I want and what is happening
Please note that 3 photos are taken in this example. The camera opens up four times. After taking each photo, I clicked 'Use Photo' on the bottom right and when the camera open on the 4th time, I clicked 'Cancel' on the bottom left to stop the loop
Thank you!
I am using iOs default PrinterToPrint in Xamarin to print without showing dialog to choose printer but then also it's showing one dialog which says printing to [PRINTER NAME]. Is there anyway to hide the dialog as well. Like complete silent print functionality?
I am not its possible but I have seen some apps which do that and I am not sure whether they are using the same function or not.
Thanks in advance.
Update:
UIPrinterPickerController comes from UIKit and as such there is no way to push the "printing" process to the background and off the main UI thread.
In the current UIPrintInteractionController.PrintToPrinter implementation (currently up to iOS 10.3 B4) there is no exposed way to disable the print progress (Connecting, Preparing, etc...) alart/dialog (w/ Cancel button) or to modify its appearance.
This interface is high level wrapper using AirPrint and thus Internet Print Protocol (IPP) at a lower level to preform the actual printing, job queue monitoring on the printer, etc... IPP is not currently exposed as a publicly available framework within iOS...
Programs that allow background printing are not using UIPrintInteractionController to do the printing. Most do use UIPrinterPickerController to obtain a UIPrinter selection from the user, but then use the UIPrinter.Url.AbsoluteUrl to "talk" directly to the printer via HTTP/HTTPS Post/Get. Depending upon the printers used, TCP-based sockets are also an option vs. IPP and even USB/serial for direct connected printers.
Re: https://en.wikipedia.org/wiki/Internet_Printing_Protocol
Original:
Pick a Printer:
if (allowUserToSelectDifferentPrinter || printerUrl == null)
{
UIPrinter uiPrinter = printerUrl != null ? null as UIPrinter : UIPrinter.FromUrl(new NSUrl(printerUrl));
var uiPrinterPickerController = UIPrinterPickerController.FromPrinter(uiPrinter);
uiPrinterPickerController.Present(true, (printerPickerController, userDidSelect, error) =>
{
if (userDidSelect)
{
uiPrinter = uiPrinterPickerController?.SelectedPrinter;
printerUrl = uiPrinter.Url.AbsoluteUrl.ToString();
Console.WriteLine($"Save this UIPrinter's Url string for later use: {printerUrl}");
}
});
}
Print using UIPrintInteractionController with an existing UIPrinter:
if (printerUrl != null)
{
// re-create a UIPrinter from a saved NSUrl string
var uiPrinter = UIPrinter.FromUrl(new NSUrl(printerUrl));
var printer = UIPrintInteractionController.SharedPrintController;
printer.ShowsPageRange = false;
printer.ShowsNumberOfCopies = false;
printer.ShowsPaperSelectionForLoadedPapers = false;
var printInfo = UIPrintInfo.PrintInfo;
printInfo.OutputType = UIPrintInfoOutputType.General;
printInfo.JobName = "StackOverflow Print Job";
var textFormatter = new UISimpleTextPrintFormatter("StackOverflow Rocks")
{
StartPage = 0,
ContentInsets = new UIEdgeInsets(72, 72, 72, 72),
MaximumContentWidth = 6 * 72,
};
printer.Delegate = new PrintInteractionControllerDelegate();
printer.PrintFormatter = textFormatter;
printer.PrintToPrinter(uiPrinter, (printInteractionController, completed, error) =>
{
if ((completed && error != null))
{
Console.WriteLine($"Print Error: {error.Code}:{error.Description}");
PresentViewController(
UIAlertController.Create("Print Error", "Code: {error.Code} Description: {error.Description}", UIAlertControllerStyle.ActionSheet),
true, () => { });
}
printInfo?.Dispose();
uiPrinter?.Dispose();
uiPrinter.
});
}
else
{
Console.WriteLine("User has not selected a printer...printing disabled");
}
I know this is a somewhat old thread but I had been struggling with implementing a silent printing in iOS for one of my customers and I finally came across an acceptable solution that is very easy to implement.
As mentioned in the accepted answer there is no way to get rid of the popup that displays printing progress. Yet there is a way of hiding it. You can simply change the UIWindowLevel of your key window to UIWindowLevel.Alert + 100. This will guarantee your current window will display above ANY alert view.
Be careful though, as I mentioned, it will be displayed over ANY alert view after the level has been changed. Luckily you can just switch this level back to "Normal" to get the original behavior.
So to recap my solution. I use UIPrintInteractionController.PrintToPrinter in order to print directly to a printer object I created using UIPrinter.FromUrl (this is Xamarin.iOS code btw). Before doing so, I adjust my window level to alert + 100 and once printing is complete I reset my window level to "Normal". Now my printing happens without any visual feedback to my user.
Hope this helps somebody!
I am having hard times debugging my code with the Dart Editor version 0.5.0_r21823 on Mac OS X.
It stops with following info:
"Dart_InstanceGetClass expects argument 'instance' to be of type Instance."
I am now trying the poor man's debugger (i.e. print ...) but even that one fails.
_setupGui() {
// Bitmap background = new Bitmap(resourceManager.getBitmapData("Pigeon"));
print("Done loading resources");
ChessBoard b = new ChessBoard();
board = new ChessBoardView(b);
stage.addChild(board);
....
/**
* Holds a chess position.
*/
class ChessBoard {
static const String STARTPOS = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
ChessBoard([String fen = STARTPOS]) {
print("ChessBoard($fen)"); // This gets written
_setFromFen(fen);
}
void _setFromFen(String fen) {
print("_setFromFEN($fen)"); // This is not written
...
Console output:
Fixed Canvas Style Size !!!!
Loading resources
Done loading resources
ChessBoard(rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1)
... here it ends. I.e. setFromFEN() is not written ...
This is likely a bug, which has likely been fixed by now. If you're using Dartium; you can use the built-in dev tools to debug (much like you would with JavaScript) which can be very convenient!
I am developing an application which makes use of camera...and my app's requirement is :
I have to take photos from my "already running" background application ; but I have to keep camera application into background......means I want to capture picture without disturbing the current foreground applications.
and in addition without making any camera shutter sound....???
Is this possible If we call camera app - through Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA, new CameraArguments())...........
thanks to all of u...specially to #donturner
.....sorry to come back on this post very late.
after some attempts I hv found that without bringing the camera screen into foreground we cant capture the snap.
1) If we put the camera screen into background OR
2) change the visibility of VideoControl's class object as false...
_videoControl.setVisible(false);
then no bytes (null value) will be received by...
byte[] imageBytes = _videoControl.getSnapshot( encoding );
So whats the use of this function....while we r using the video control class for capture snap or video???
_videoControl.setVisible(true);
I hv tried a different trick......
I call a thread just before bring the camera screen into foreground to off the back-light of the device.
then soon after that I bring the camera screen into foreground and capture the snap.
I hv tested the above trick on BB Flip (4.6) and Storm (5.0) devices and it takes snapshots successfully even when device back light is OFF.
But now I become stuck on some other problem....and that is the camera SHUTTER sound. I hv tried a lot but couldn't get success to mute it....
as #Michael Donohue suggested, I hv tried..
private void muteThread() {
Thread t = new Thread(new Runnable() {
public void run() {
try {
int i = 0;
while (i < 50) {
Audio.setVolume(0);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
i++;
}
System.out.println("\n\n >>>>> End of Mute Thread. <<<< \n\n");
} catch (Exception e) {
}
}
});
t.start();
}
but it is not working... If this cant be done then how these application r providing this facility...and wht kind of functionality they hv used.
http://appworld.blackberry.com/webstore/content/97648/?lang=en
http://appworld.blackberry.com/webstore/content/79083/?lang=en
You cannot take a photo programmatically without displaying the camera preview feed to the user so at the very minimum you need to bring the camera preview surface into the UI foreground.
I have a MonoTouch application that loads a frame every 1/12th of second. I'm using the UIkit, not opengl. I have an UIImage into the view, and with a backgroundtask i'm loading the images.
Everything is ok, but, after a minute (more or less), the application stops, and the tracer gives me a 'low memory pressure'
It works fine in the emulator, with no problems. I'm looking at the profiler and it seems that the memory is disposed, but when i try it on the iPad.... :(
I free the memory using image.Dispose(). I have 2 images in memory, showing one of then and then releasing the older. This behaviour is ok, because i have the same logic on the Windows Phone and it works fine.
I've tried not to use the backgroundTask, and load the image directly from the main Thread. It gives me more time!!! If i use the backgroundTask, the application runs for 30 seconds and then exits . If i NOT use the backgroundTask, it lasts 1 minute.
I don't know what to do!!!! Can anyone help me, please?
Thanks!!!
Texture2D.FromStream it's only a wrapper for UIImage.FromFile
This is the background worker:
void LoadTextureInBackground()
{
if (currentMovie == null) return;
DateTime timeOnstart = DateTime.Now;
// Mantenemos 2 texturas en memoria para no cargar sobre el mismo objeto texture.
string fileName = currentMovie.GetFileName();
if (lastFileName == fileName) return;
textureLoaded[currentTexture] = Texture2D.FromStream(Device.GraphicsDevice, fileName);
texture = textureLoaded[currentTexture];
currentTexture = 1 - currentTexture;
lastFileName = fileName;
GC.Collect();
System.Threading.Thread.Sleep(50);
}
This is the draw method:
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public void Draw(TimeSpan totalTime,TimeSpan elapsedTime)
{
if(currentMovie==null) return;
// Mantenemos 2 texturas en memoria para no cargar sobre el mismo objeto texture.
if (texture == null) return;
int newWidth = (int)(texture.Width*RenderSize);
int newHeight = (int)(texture.Height*RenderSize);
Texture2D drawTexture = texture;
// Al cargar usando Texture2D.FromStream, la textura NO lleva elAlpha premultiplicado
//Device.SpriteBatch.Draw(drawTexture, destination, Color.White);
if(CultTravel.AppDelegate.ImagePng.Image!=drawTexture.Texture)
{
AppDelegate.ImagePng.Image=drawTexture.Texture;
AppDelegate.ImagePng.Frame=new System.Drawing.RectangleF(0,480-newHeight,ImagePng.Image.CGImage.Width,newHeight);
// Si la textura que tengo cargada y lista para mostrar es diferente a la que mostraba, libero la antigua
if (lastTextureDraw!=null && lastTextureDraw != texture)
{
lastTextureDraw.Dispose();
}
lastTextureDraw = texture;
}
Note:
I've just solved the issue, BUT i have to disable the background worker, add the loading code in the Draw method and add the GC.Collect in the main thread:
if (lastTextureDraw!=null && lastTextureDraw != texture)
{
lastTextureDraw.Dispose();
// I MUST ADD THIS TO WORK AND DISABLE THE BACKGROUND TASK!!
GC.Collect();
}
I've just solved the issue, BUT i have to disable the background worker, add the loading code in the Draw method and add the GC.Collect in the main thread:
if (lastTextureDraw!=null && lastTextureDraw != texture)
{
lastTextureDraw.Dispose();
// I MUST ADD THIS TO WORK AND DISABLE THE BACKGROUND TASK!!
GC.Collect();
}
So, something is wrong when working with threads....
It works fine in the emulator, with no problems.
This is not an emulator but a simulator. As such it does not try to mimic a specific device, including it's memory restrictions. IOW the iOS simulator has access to much more memory than your iPad (1st gen 256MB, 2nd gen 512MB, 3rd gen 1GB).
I'm looking at the profiler
Which one ? MonoDevelop's HeapShot or Apple's Instruments ?
I free the memory using image.Dipose().
That's a good idea - but it could only work on the managed side. E.g. some API will cache images, that memory won't show on HeapShot since it's not managed memory (it's natively allocated memory). You'll have a better chance to track this using Apple's Instruments.
It could be something else too... which means, like #Jonathan.Peppers asked, that seeing how you're loading the images could help us to see what's wrong.