Open phone camera using jquery mobile and phonegap/cordova - jquery-mobile

Some one has idea how can i direct open the phone camera of android/ios/windows from phone web browser using the phonegap/cordova js.
Thnx..

create Phonegap Project by following this , after creating project just add camera plugin
just look at this link.
now
you can able to open camera by calling this method
navigator.camera.getPicture( cameraSuccess, cameraError, [ cameraOptions ] );
The camera.getPicture function opens the device's default camera application that allows users to snap pictures. This behavior occurs by default, when Camera.sourceType equals Camera.PictureSourceType.CAMERA. Once the user snaps the photo, the camera application closes and the application is restored.
If Camera.sourceType is Camera.PictureSourceType.PHOTOLIBRARY or Camera.PictureSourceType.SAVEDPHOTOALBUM, then a dialog displays that allows users to select an existing image. The camera.getPicture function returns a CameraPopoverHandle object, which can be used to reposition the image selection dialog, for example, when the device orientation changes.
The return value is sent to the cameraSuccess callback function, in one of the following formats, depending on the specified cameraOptions:
A String containing the base64-encoded photo image.
A String representing the image file location on local storage (default).
You can do whatever you want with the encoded image or URI, for example:
Render the image in an <img> tag, as in the example below
Save the data locally (LocalStorage, Lawnchair, etc.)
Post the data to a remote server
MORE INFO check the above link

open terminal or cmd and create project for phonegap,
For create project you must require installed nodejs and git in your system,
write this command and install plguin.
phonegap local plugin add
There is reference of html and js for camera code
if you don't want to use phoengap and open camera than use pure html5 Camera but its some limiation of versioning problem

Try this in your app code and use < input type= 'file' > in your html code
public class MyWb extends Activity {
/** Called when the activity is first created. */
WebView web;
ProgressBar progressBar;
private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE=1;
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if(requestCode==FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage) return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
web = (WebView) findViewById(R.id.webview01);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
web = new WebView(this);
web.getSettings().setJavaScriptEnabled(true);
web.loadUrl("http://www.script-tutorials.com/demos/199/index.html");
web.setWebViewClient(new myWebClient());
web.setWebChromeClient(new WebChromeClient()
{
//The undocumented magic method override
//Eclipse will swear at you if you try to put #Override here
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MyWb.this.startActivityForResult(Intent.createChooser(i,"File Chooser"), FILECHOOSER_RESULTCODE);
}
// For Android 3.0+
public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MyWb.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}
//For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MyWb.this.startActivityForResult( Intent.createChooser( i, "File Chooser" ), MyWb.FILECHOOSER_RESULTCODE );
}
});
setContentView(web);
}
public class myWebClient extends WebViewClient
{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
}
//flipscreen not loading again
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
// To handle "Back" key press event for WebView to go back to previous screen.
/*#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) {
web.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}*/

<!DOCTYPE html>
<html>
<head>
<title>Capture Photo</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
<script type="text/javascript" charset="utf-8">
var pictureSource; // picture source
var destinationType; // sets the format of returned value
// Wait for Cordova to connect with the device
//
document.addEventListener("deviceready",onDeviceReady,false);
// Cordova is ready to be used!
//
function onDeviceReady() {
pictureSource=navigator.camera.PictureSourceType;
destinationType=navigator.camera.DestinationType;
}
// Called when a photo is successfully retrieved
//
function onPhotoDataSuccess(imageData) {
// Uncomment to view the base64 encoded image data
// console.log(imageData);
// Get image handle
//
var smallImage = document.getElementById('smallImage');
// Unhide image elements
//
smallImage.style.display = 'block';
// Show the captured photo
// The inline CSS rules are used to resize the image
//
smallImage.src = "data:image/jpeg;base64," + imageData;
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
// Uncomment to view the image file URI
// console.log(imageURI);
// Get image handle
//
var largeImage = document.getElementById('largeImage');
// Unhide image elements
//
largeImage.style.display = 'block';
// Show the captured photo
// The inline CSS rules are used to resize the image
//
largeImage.src = imageURI;
}
// A button will call this function
//
function capturePhoto() {
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
destinationType: destinationType.DATA_URL });
}
// A button will call this function
//
function capturePhotoEdit() {
// Take picture using device camera, allow edit, and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 20, allowEdit: true,
destinationType: destinationType.DATA_URL });
}
// A button will call this function
//
function getPhoto(source) {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
destinationType: destinationType.FILE_URI,
sourceType: source });
}
// Called if something bad happens.
//
function onFail(message) {
alert('Failed because: ' + message);
}
</script>
</head>
<body>
<button onclick="capturePhoto();">Capture Photo</button> <br>
<button onclick="capturePhotoEdit();">Capture Editable Photo</button> <br>
<button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">From Photo Library</button><br>
<button onclick="getPhoto(pictureSource.SAVEDPHOTOALBUM);">From Photo Album</button><br>
<img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
<img style="display:none;" id="largeImage" src="" />
</body>
</html>

Related

How to save changes to firebase document if user closes window or tab

Context: I have a use case where in the components used is firebase realtime database in Polymer 2.x. I have a function that does transformations on certain user activity with the firebase realtime object. I used polymerfire webcomponent.
What I want is: on user closes tab or window, save the data into firebase realtime database and then close the window.
Result: I used on beforeunload of window in the script of the polymer element. But not able to fire a method inside polymer element that triggers storage of the data in realtime db.
What I am looking for:
1. A way to initiate the element public function from script of an element.
Or
2. a better way to implement on window/tab close save the data
Thanks.
Code:
<!DOCTYPE html>
<dom-module id="t-page">
<template is="dom-bind">
....
</template>
<script>
var myEvent = window.attachEvent || window.addEventListener;
var chkevent = window.attachEvent ? 'onbeforeunload' :
'beforeunload'; /// make IE7, IE8 compitable
myEvent(chkevent, async function (e) { // For >=IE7, Chrome, Firefox
var confirmationMessage = 'Are you sure to leave the page?'; // a space
(e || window.event).returnValue = confirmationMessage;
setTimeout(async () => {
document.getElementById('trello-page').onCloseWindow();
}, 2500);
return confirmationMessage;
});
/**
* #polymer
* #extends HTMLElement
*/
class TPage extends Polymer.Element {
static get is() {
return 't-page';
}
... some properties ....{ colUpdateArr{...}}
async onCloseWindow() {
for (var i = 0; i < this.colUpdateArr.length; i += 2) {
var toCol = this.colUpdateArr[i];
var fromCol = this.colUpdateArr[i + 1];
await this.$.query.ref.child(toCol.$key).child('tasks').set(toCol.tasks);
await this.$.query.ref.child(fromCol.$key).child('tasks').set(fromCol.tasks);
}
}
} //end Polymer.Element
window.customElements.define(TPage.is, TPage);
</script>
</dom-module>

How to get all PDF files from internal as well as external storage in Flutter?

I want to show All pdf files present in internal as well as external storage, So on tapping that particular file, i want to open that file in full screen dialog.
So in order to do that you need to:
Grant access to external storage in a directory where there are your PDF file. Let's call that folder <external storage>/pdf.
List all file of that directory a display them to the user.
Open the selected file with an application that can visualize PDF.
In order to do all that thinks I suggest you to use those flutter packages:
path_provider
simple_permission
With path_provider you can get the external storage directory of an Android device.
Directory extDir = await getExternalStorageDirectory();
String pdfPath = extDir + "/pdf/";
In order to access external storage you need to set this permission request in the ApplicationManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You could also only use READ_EXTERNAL_STORAGE but then the simple_permission plugin won't work.
With the simple_permission plugin then you go and ask user to be granted external storage access:
bool externalStoragePermissionOkay = false;
_checkPermissions() async {
if (Platform.isAndroid) {
SimplePermissions
.checkPermission(Permission.WriteExternalStorage)
.then((checkOkay) {
if (!checkOkay) {
SimplePermissions
.requestPermission(Permission.WriteExternalStorage)
.then((okDone) {
if (okDone) {
debugPrint("${okDone}");
setState(() {
externalStoragePermissionOkay = okDone;
debugPrint('Refresh UI');
});
}
});
} else {
setState(() {
externalStoragePermissionOkay = checkOkay;
});
}
});
}
}
Once we have been granted external storage access we an list our PDF directory:
List<FileSystemEntity> _files;
_files = dir.listSync(recursive: true, followLinks: false);
And show them in a ListView:
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: _files.length,
itemBuilder: (context, i) {
return _buildRow(_files.elementAt(i).path);
});
Than you have to open them with a viewer when the user tap on them.
To do that there isn't an easy way, because with Android we need to build a ContentUri and give access to this URI to the exteranl application viewer.
So we do that in Android and we use flutter platform channels to call the Android native code.
Dart:
static const platform =
const MethodChannel('it.versionestabile.flutterapp000001/pdfViewer');
var args = {'url': fileName};
platform.invokeMethod('viewPdf', args);
Native Java Code:
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "it.versionestabile.flutterapp000001/pdfViewer";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
#Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("viewPdf")) {
if (call.hasArgument("url")) {
String url = call.argument("url");
File file = new File(url);
//*
Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".provider",
file);
//*/
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(photoURI,"application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(target);
result.success(null);
}
} else {
result.notImplemented();
}
}
});
}
}
And after all we can have our PDF list and viewable on Android.
You have a lot to study. I hope this could be an useful playground for you.
This is for External Storage, but you can get Also the Internal and Temporary directory and act similarly as here.
If you wanna do the same thing on iOS you need to create the same Native Code pdfViewer also on iOS project. Refer alway to flutter platform channels in order to do it. And remember that the external storage doesn't exists on iOS devices. So you could use only the application sandbox document folder or the temporary one.
GitHub repo.
Happy coding.
i use this code for list files and directories
Future<List<FileSystemEntity>> dirContents(Directory dir) {
var files = <FileSystemEntity>[];
var completer = Completer<List<FileSystemEntity>>();
var lister = dir.list(recursive: false);
lister.listen((file) async {
FileStat f = file.statSync();
if (f.type == FileSystemEntityType.directory) {
await dirContents(Directory(file.uri.toFilePath()));
} else if (f.type == FileSystemEntityType.file && file.path.endsWith('.pdf')) {
_files.add(file);
}
}, onDone: () {
completer.complete(files);
setState(() {
//
});
});
return completer.future;
}
Directory dir = Directory('/storage/emulated/0');
var files = await dirContents(dir);
print(files);
Here is my code to list files from the download folder
List<dynamic> filesList = [];
Future listDir() async {
Directory dir = Directory(
'/storage/emulated/0/Download');
await for (FileSystemEntity entity
in dir.list(recursive: true, followLinks: false)) {
FileSystemEntityType type = await FileSystemEntity.type(entity.path);
if (type == FileSystemEntityType.file &&
entity.path.endsWith('.pdf')) {
filesList.add(entity.path);
}
}
return filesList;}

iOS callback not triggered after file upload from $cordovaCamera

I'm building a hybrid app in ionic, which runs over cordova. I use the $cordovaCamera plugin to capture images from the phone, either by selecting from the phone's gallery or by using the camera to take a picture.
I then send that image using Restangular to my server, and when that action finishes, I want to display a status message on the screen.
My problem: All of the above works perfectly on Android. On iOS, it is working only when the image is selected from the gallery, but not when the image is directly captured from the phone. In that case, the image is correctly transferred to the server, the request returns a 201 Created just as it should - but the then() callback function is never entered.
If anyone can explain this behavior, that would be awesome...my second best would be to capture the image on the iPhone, save to gallery, and then attempt to retrieve the last saved image, but I haven't been able to figure out how to yet and I'd rather just get this working.
Update: I've narrowed it down to the Restangular part - if instead of calling the Restangular upload function, I use $http, the callback is triggered as expected and all is good...so that's what I'm going to do, but if anyone can tell me what the problem was I'd be grateful.
Relevant code:
/** cameraService functions **/
//when the user chooses to snap a picture from the camera
takePicture: function(){
var options = {
quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
//when the user chooses to select image from the gallery
choosePicture: function(){
var options = {
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
uploadPicture: function(imageSource, caption, is_logo){
if (typeof is_logo == 'undefined') is_logo = false;
var upload_object = {
caption: caption,
source: imageSource,
is_logo: is_logo
};
//apiService is my wrapper for Restangular
return apiService.uploadFile(loadingService.getClientUrl('images'), upload_object);
},
/**apiService uploadFile - apparently the problem is here ***/
uploadFile: function(baseElem, object, route, path){
var headers = apiFunctions.setHeaders({'Content-Type': undefined});
//this DOES NOT WORK (on iPhone with image from camera) - request completes but callback not triggered
return Restangular.all(baseElem).customPOST(object, path, route, headers);
//this works fine:
return $http.post('https://api.mysite.dev/v1/clients/'+localStorageService.getValue('client_id')+'/images', JSON.stringify(object), {headers:headers}
);
},
/** controller functions **/
$scope.takePicture = function () {
cameraService.takePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.choosePicture = function () {
cameraService.choosePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.uploadPicture = function () {
cameraService.uploadPicture($scope.data.imageSource, $scope.data.caption)
.then(function (response) { //this is never entered if image is captured from camera on iPhone
$ionicScrollDelegate.scrollTop();
$scope.data.caption = '';
$scope.data.imageSource = '';
if (response.data.response.is_success.data_value == true) {
$scope.messages.success.push("Photo uploaded successfully");
} else {
$scope.messages.failure.push("Error uploading photo.");
}
});
}

Print barcodes from web page to Zebra printer

We're trying to print barcodes from a web page to our Zebra printer.
I'm wondering if there's a way to print them using the printer's own font perhaps using web fonts or if I knew the font name used?
I have been trying to use php barcode generators, that basically generates images containing the barcode. I have in fact been trying this approach for a few days already, without success.
The problem is when I print them it's not readable by the scanners. I have tried to change the image resolution to match that of the printer (203dpi), also tried playing with the image size and formats, but the barcodes after printed still can't be scanned.
So does anybody have experience with this?
Printer: Zebra TLP 2844
Barcodes required per page:
01 Code39 horizontal (scanable only if printed at very specific size and browser)
01 Code128 vertical (still can't get it to work, print is always very blurry and won't get scanned)
===========
I've made a little bit of progress, I found out this printer supports EPL2 language, so I'm trying to use it to print out the barcodes.
First I needed to enable pass through mode, I did that on Printer Options > Advanced Setup > Miscellaneous.
Now I'm able to print barcodes impeccably using the printer's built-in font :D using this command:
ZPL:
B10,10,0,1,2,2,60,N,"TEXT-GOES-HERE"
:ZPL
But I can only print it from Notepad, I'm still unable to print this from a browser... It's probably a problem with LF being replaced with CR+LF...
How to overcome this problem??
===========
The label I'm trying to print actually has a bit of text before the barcode, with some html tables formatting it nicely. So I need to print this first, and in the middle I need to stick in a nice label and then add some more text.
So I can't use pure EPL2 to print the whole thing, I'm wondering if I can use some of both html + EPL2 + html to achieve my goal or is that not allowed?? =/
You are running into a few obstacles:
1) When you print through the OS installed printer driver, the printer driver is trying to take the data that is sent to it and (re)rasterize or scale it for the output device (the Zebra printer). Since the printer is a relatively low resolution at 203dpi, then it does not take too much for the scaling the print driver is having to do for it to loose some integrity in the quality of the barcode. This is why barcodes generated using the direct ZPL commands are much more reliable.
2) Due to the security that web browsers purposefully provide by not allowing access to the client computer, you cannot directly communicate with the client connected printer. This sandboxing is what helps to protect users from malware so that nefarious websites cannot do things like write files to the client machine or send output directly to devices such as printers. So you are not able to directly send the ZPL commands through the browser to the client connected printer.
However, there is a way to do what you describe. The steps necessary are typically only going to be useful if you have some degree of control over the client computer accessing the site that is trying to print to the Zebra printers. For example this is only going to be used by machines on your company network, or by clients who are willing to install a small application that you need to write. To do this, you will need to look at the following steps:
A) You need to make up your own custom MIME type. This is basically just any name you want to use that is not going to collide with any registered MIME types.
B) Next you will define a filename extension that will map to your custom MIME type. To do this, you typically will need to configure your web server (steps for this depend on what web server you are using) to allow the new MIME type you want to define and what file extension is used for these types of files.
C) Then on your web application, when you want to output the ZPL data, you write it to a file using a filename extension that is mapped to your new MIME type. Then once the file is generated, you can either provide an HTML link to it, or redirect the client browser to the file. You can test if your file is working correctly at this point by manually copying the file you created directly to the raw printer port.
D) Next you need to write a small application which can be installed on the client. When the application is installed, you need to have it register itself as a valid consuming application for your custom MIME type. If a browser detects that there is an installed application for a file of the specified MIME type, it simply writes the file to a temporary directory on the client machine and then attempts to launch the application of the same registered MIME type with the temporary file as a parameter to the application. Thus your application now just reads the file that the browser passed to it and then it attempts to dump it directly to the printer.
This is an overview of what you need to do in order to accomplish what you are describing. Some of the specific steps will depend on what type of web server you are using and what OS your clients machines are. But this is the high level overview that will let you accomplish what you are attempting.
If you'd consider loading a java applet, qz-print (previously jzebra) can do exactly what you are describing and works nicely with the LP2844 mentioned in the comments.
https://code.google.com/p/jzebra/
What we did for our web app :
1) Download the free printfile app http://www.lerup.com/printfile/
"PrintFile is a freeware MS Windows utility program that will enable you to print files fast and easily. The program recognizes plain text, PostScript, Encapsulated PostScript (EPS) and binary formats. Using this program can save you a lot of paper and thereby also saving valuable natural resources."
When you first run PrintFile, go into the advanced options and enable "send to printer directly".
2) Setup the ZEBRA printer in windows as a Generic Text Printer.
2) Generate a file.prt file in the web app which is just a plain text EPL file.
3) Double clicking on the downloaded file will instantly print the barcode. Works like a charm. You can even setup PrintFile so that you don't even see a gui.
I am using QZ Tray to print labels from a web page to Zebra thermal printer.
In the demo/js folder of QZ Tray there are three JavaScript files that are required to communicate with QZ Tray application - dependencies/rsvp-3.1.0.min.js, dependencies/sha-256.min.js and qz-tray.js.
Include these JavaScript files in your project as follows:
<script type="text/javascript" src="/lib/qz-tray/rsvp-3.1.0.min.js"></script>
<script type="text/javascript" src="/lib/qz-tray/sha-256.min.js"></script>
<script type="text/javascript" src="/lib/qz-tray/qz-tray.js"></script>
The most simple way to print a label to Zebra thermal printer is shown below.
<script type="text/javascript">
qz.websocket.connect().then(function() {
// Pass the printer name into the next Promise
return qz.printers.find("zebra");
}).then(function(printer) {
// Create a default config for the found printer
var config = qz.configs.create(printer);
// Raw ZPL
var data = ['^XA^FO50,50^ADN,36,20^FDRAW ZPL EXAMPLE^FS^XZ'];
return qz.print(config, data);
}).catch(function(e) { console.error(e); });
</script>
See How to print labels from a web page to Zebra thermal printer for more information.
You can also send the ZPL commands in a text file (you can pack multiple labels in a single file) and have the user open and print the file via windows notepad. The only caveat is that they have to remove the default header and footer (File --> Page Setup).
Its a bit of user training, but may be acceptable if you don't have control over the client machines.
I'm developing something similar here.
I need to print in a LP2844 from my webapp. The problem is that my webapp is in a remote server in the cloud (Amazon EC2) and the printer is going to be in a warehouse desk.
My solution:
The webapp generates the EPL2 code for the label with the barcodes, then publish a PubNub message.
I wrote a little C# program that runs in the computer where the printer is connected. The program receives the message and then send the code to the printer.
I followed the idea proposed by "Tres Finocchiaro" on my application based on:
ASP.NET 4.0
IIS
Chrome, IExplorer, Firefox
Zebra TLP 2844
EPL protocolo
Unfortunatly the jzebra needs some improvements to work corectly due to the issues of security of current browser.
Installing jzebra
Downlod jzebdra and from dist directory I copy into your directory (eg. mydir):
web
mydir
js
..
deployJava.js
lib
..
qz-print.jar
qz-print_jnlp.jnlp
Create your print.html
<html>
<script type="text/javascript" src="js/deployJava.js"></script>
<script type="text/javascript">
/**
* Optionally used to deploy multiple versions of the applet for mixed
* environments. Oracle uses document.write(), which puts the applet at the
* top of the page, bumping all HTML content down.
*/
deployQZ();
/** NEW FUNCTION **/
function initPrinter() {
findPrinters();
useDefaultPrinter();
}
/** NEW FUNCTION **/
function myalert(txt) {
alert(txt);
}
/**
* Deploys different versions of the applet depending on Java version.
* Useful for removing warning dialogs for Java 6. This function is optional
* however, if used, should replace the <applet> method. Needed to address
* MANIFEST.MF TrustedLibrary=true discrepency between JRE6 and JRE7.
*/
function deployQZ() {
var attributes = {id: "qz", code:'qz.PrintApplet.class',
archive:'qz-print.jar', width:1, height:1};
var parameters = {jnlp_href: 'qz-print_jnlp.jnlp',
cache_option:'plugin', disable_logging:'false',
initial_focus:'false'};
if (deployJava.versionCheck("1.7+") == true) {}
else if (deployJava.versionCheck("1.6+") == true) {
delete parameters['jnlp_href'];
}
deployJava.runApplet(attributes, parameters, '1.5');
}
/**
* Automatically gets called when applet has loaded.
*/
function qzReady() {
// Setup our global qz object
window["qz"] = document.getElementById('qz');
var title = document.getElementById("title");
if (qz) {
try {
title.innerHTML = title.innerHTML + " " + qz.getVersion();
document.getElementById("content").style.background = "#F0F0F0";
} catch(err) { // LiveConnect error, display a detailed meesage
document.getElementById("content").style.background = "#F5A9A9";
alert("ERROR: \nThe applet did not load correctly. Communication to the " +
"applet has failed, likely caused by Java Security Settings. \n\n" +
"CAUSE: \nJava 7 update 25 and higher block LiveConnect calls " +
"once Oracle has marked that version as outdated, which " +
"is likely the cause. \n\nSOLUTION: \n 1. Update Java to the latest " +
"Java version \n (or)\n 2. Lower the security " +
"settings from the Java Control Panel.");
}
}
}
/**
* Returns whether or not the applet is not ready to print.
* Displays an alert if not ready.
*/
function notReady() {
// If applet is not loaded, display an error
if (!isLoaded()) {
return true;
}
// If a printer hasn't been selected, display a message.
else if (!qz.getPrinter()) {
/** CALL TO NEW FUNCTION **/
initPrinter();
return false;
}
return false;
}
/**
* Returns is the applet is not loaded properly
*/
function isLoaded() {
if (!qz) {
alert('Error:\n\n\tPrint plugin is NOT loaded!');
return false;
} else {
try {
if (!qz.isActive()) {
alert('Error:\n\n\tPrint plugin is loaded but NOT active!');
return false;
}
} catch (err) {
alert('Error:\n\n\tPrint plugin is NOT loaded properly!');
return false;
}
}
return true;
}
/**
* Automatically gets called when "qz.print()" is finished.
*/
function qzDonePrinting() {
// Alert error, if any
if (qz.getException()) {
alert('Error printing:\n\n\t' + qz.getException().getLocalizedMessage());
qz.clearException();
return;
}
// Alert success message
alert('Successfully sent print data to "' + qz.getPrinter() + '" queue.');
}
/***************************************************************************
* Prototype function for finding the "default printer" on the system
* Usage:
* qz.findPrinter();
* window['qzDoneFinding'] = function() { alert(qz.getPrinter()); };
***************************************************************************/
function useDefaultPrinter() {
if (isLoaded()) {
// Searches for default printer
qz.findPrinter();
// Automatically gets called when "qz.findPrinter()" is finished.
window['qzDoneFinding'] = function() {
// Alert the printer name to user
var printer = qz.getPrinter();
myalert(printer !== null ? 'Default printer found: "' + printer + '"':
'Default printer ' + 'not found');
// Remove reference to this function
window['qzDoneFinding'] = null;
};
}
}
/***************************************************************************
* Prototype function for finding the closest match to a printer name.
* Usage:
* qz.findPrinter('zebra');
* window['qzDoneFinding'] = function() { alert(qz.getPrinter()); };
***************************************************************************/
function findPrinter(name) {
// Get printer name from input box
var p = document.getElementById('printer');
if (name) {
p.value = name;
}
if (isLoaded()) {
// Searches for locally installed printer with specified name
qz.findPrinter(p.value);
// Automatically gets called when "qz.findPrinter()" is finished.
window['qzDoneFinding'] = function() {
var p = document.getElementById('printer');
var printer = qz.getPrinter();
// Alert the printer name to user
alert(printer !== null ? 'Printer found: "' + printer +
'" after searching for "' + p.value + '"' : 'Printer "' +
p.value + '" not found.');
// Remove reference to this function
window['qzDoneFinding'] = null;
};
}
}
/***************************************************************************
* Prototype function for listing all printers attached to the system
* Usage:
* qz.findPrinter('\\{dummy_text\\}');
* window['qzDoneFinding'] = function() { alert(qz.getPrinters()); };
***************************************************************************/
function findPrinters() {
if (isLoaded()) {
// Searches for a locally installed printer with a bogus name
qz.findPrinter('\\{bogus_printer\\}');
// Automatically gets called when "qz.findPrinter()" is finished.
window['qzDoneFinding'] = function() {
// Get the CSV listing of attached printers
var printers = qz.getPrinters().split(',');
for (i in printers) {
myalert(printers[i] ? printers[i] : 'Unknown');
}
// Remove reference to this function
window['qzDoneFinding'] = null;
};
}
}
/***************************************************************************
* Prototype function for printing raw EPL commands
* Usage:
* qz.append('\nN\nA50,50,0,5,1,1,N,"Hello World!"\n');
* qz.print();
***************************************************************************/
function print() {
if (notReady()) { return; }
// Send characters/raw commands to qz using "append"
// This example is for EPL. Please adapt to your printer language
// Hint: Carriage Return = \r, New Line = \n, Escape Double Quotes= \"
qz.append('\nN\n');
qz.append('q609\n');
qz.append('Q203,26\n');
qz.append('B5,26,0,1A,3,7,152,B,"1234"\n');
qz.append('A310,26,0,3,1,1,N,"SKU 00000 MFG 0000"\n');
qz.append('A310,56,0,3,1,1,N,"QZ PRINT APPLET"\n');
qz.append('A310,86,0,3,1,1,N,"TEST PRINT SUCCESSFUL"\n');
qz.append('A310,116,0,3,1,1,N,"FROM SAMPLE.HTML"\n');
qz.append('A310,146,0,3,1,1,N,"QZINDUSTRIES.COM"');
// Append the rest of our commands
qz.append('\nP1,1\n');
// Tell the applet to print.
qz.print();
}
/***************************************************************************
* Prototype function for logging a PostScript printer's capabilites to the
* java console to expose potentially new applet features/enhancements.
* Warning, this has been known to trigger some PC firewalls
* when it scans ports for certain printer capabilities.
* Usage: (identical to appendImage(), but uses html2canvas for png rendering)
* qz.setLogPostScriptFeatures(true);
* qz.appendHTML("<h1>Hello world!</h1>");
* qz.printPS();
***************************************************************************/
function logFeatures() {
if (isLoaded()) {
var logging = qz.getLogPostScriptFeatures();
qz.setLogPostScriptFeatures(!logging);
alert('Logging of PostScript printer capabilities to console set to "' + !logging + '"');
}
}
/***************************************************************************
****************************************************************************
* * HELPER FUNCTIONS **
****************************************************************************
***************************************************************************/
function getPath() {
var path = window.location.href;
return path.substring(0, path.lastIndexOf("/")) + "/";
}
/**
* Fixes some html formatting for printing. Only use on text, not on tags!
* Very important!
* 1. HTML ignores white spaces, this fixes that
* 2. The right quotation mark breaks PostScript print formatting
* 3. The hyphen/dash autoflows and breaks formatting
*/
function fixHTML(html) {
return html.replace(/ /g, " ").replace(/’/g, "'").replace(/-/g,"‑");
}
/**
* Equivelant of VisualBasic CHR() function
*/
function chr(i) {
return String.fromCharCode(i);
}
/***************************************************************************
* Prototype function for allowing the applet to run multiple instances.
* IE and Firefox may benefit from this setting if using heavy AJAX to
* rewrite the page. Use with care;
* Usage:
* qz.allowMultipleInstances(true);
***************************************************************************/
function allowMultiple() {
if (isLoaded()) {
var multiple = qz.getAllowMultipleInstances();
qz.allowMultipleInstances(!multiple);
alert('Allowing of multiple applet instances set to "' + !multiple + '"');
}
}
</script>
<input type="button" onClick="print()" />
</body>
</html>
the code provided is based on "jzebra_installation/dist/sample.html".
try creating a websocket that controls the print on the client side and send data with ajax from the page to localhost.
/// websocket
using System;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
namespace Server
{
class Program
{
public static WebsocketServer ws;
static void Main(string[] args)
{
ws = new Server.WebsocketServer();
ws.LogMessage += Ws_LogMessage;
ws.Start("http://localhost:2645/service/");
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
private static void Ws_LogMessage(object sender, WebsocketServer.LogMessageEventArgs e)
{
Console.WriteLine(e.Message);
}
}
public class WebsocketServer
{
public event OnLogMessage LogMessage;
public delegate void OnLogMessage(Object sender, LogMessageEventArgs e);
public class LogMessageEventArgs : EventArgs
{
public string Message { get; set; }
public LogMessageEventArgs(string Message)
{
this.Message = Message;
}
}
public bool started = false;
public async void Start(string httpListenerPrefix)
{
HttpListener httpListener = new HttpListener();
httpListener.Prefixes.Add(httpListenerPrefix);
httpListener.Start();
LogMessage(this, new LogMessageEventArgs("Listening..."));
started = true;
while (started)
{
HttpListenerContext httpListenerContext = await httpListener.GetContextAsync();
if (httpListenerContext.Request.IsWebSocketRequest)
{
ProcessRequest(httpListenerContext);
}
else
{
httpListenerContext.Response.StatusCode = 400;
httpListenerContext.Response.Close();
LogMessage(this, new LogMessageEventArgs("Closed..."));
}
}
}
public void Stop()
{
started = false;
}
private async void ProcessRequest(HttpListenerContext httpListenerContext)
{
WebSocketContext webSocketContext = null;
try
{
webSocketContext = await httpListenerContext.AcceptWebSocketAsync(subProtocol: null);
LogMessage(this, new LogMessageEventArgs("Connected"));
}
catch (Exception e)
{
httpListenerContext.Response.StatusCode = 500;
httpListenerContext.Response.Close();
LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0}", e)));
return;
}
WebSocket webSocket = webSocketContext.WebSocket;
try
{
while (webSocket.State == WebSocketState.Open)
{
ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]);
WebSocketReceiveResult result = null;
using (var ms = new System.IO.MemoryStream())
{
do
{
result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, result.Count);
}
while (!result.EndOfMessage);
ms.Seek(0, System.IO.SeekOrigin.Begin);
if (result.MessageType == WebSocketMessageType.Text)
{
using (var reader = new System.IO.StreamReader(ms, Encoding.UTF8))
{
var r = System.Text.Encoding.UTF8.GetString(ms.ToArray());
var t = Newtonsoft.Json.JsonConvert.DeserializeObject<Datos>(r);
bool valid = true;
byte[] toBytes = Encoding.UTF8.GetBytes(""); ;
if (t != null)
{
if (t.printer.Trim() == string.Empty)
{
var printers = "";
foreach (var imp in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
printers += imp + "\n";
}
toBytes = Encoding.UTF8.GetBytes("No se Indicó la Impresora\nLas Impresoras disponibles son: " + printers);
valid = false;
}
if (t.name.Trim() == string.Empty)
{
toBytes = Encoding.UTF8.GetBytes("No se Indicó el nombre del Documento");
valid = false;
}
if (t.code == null)
{
toBytes = Encoding.UTF8.GetBytes("No hay datos para enviar a la Impresora");
valid = false;
}
if (valid)
{
print.RawPrinter.SendStringToPrinter(t.printer, t.code, t.name);
toBytes = Encoding.UTF8.GetBytes("Correcto...");
}
await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None);
}
else
{
toBytes = Encoding.UTF8.GetBytes("Error...");
await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None);
}
}
}
}
}
}
catch (Exception e)
{
LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0} \nLinea:{1}", e, e.StackTrace)));
}
finally
{
if (webSocket != null)
webSocket.Dispose();
}
}
}
public class Datos
{
public string name { get; set; }
public string code { get; set; }
public string printer { get; set; } = "";
}
}
raw Print:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
namespace print
{
public class RawPrinter
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)]
string szPrinter, ref IntPtr hPriknter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In(), MarshalAs(UnmanagedType.LPStruct)]
DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, ref Int32 dwWritten);
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount, string DocName = "")
{
Int32 dwError = 0;
Int32 dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false;
// Assume failure unless you specifically succeed.
di.pDocName = string.IsNullOrEmpty(DocName) ? "My C#.NET RAW Document" : DocName;
di.pDataType = "RAW";
// Open the printer.
if (OpenPrinter(szPrinterName.Normalize(), ref hPrinter, IntPtr.Zero))
{
// Start a document.
if (StartDocPrinter(hPrinter, 1, di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength = 0;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
public static bool SendStringToPrinter(string szPrinterName, string szString, string DocName = "")
{
IntPtr pBytes = default(IntPtr);
Int32 dwCount = default(Int32);
// How many characters are in the string?
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount, DocName);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
}
html page:
<!DOCTYPE html>
<html>
<head>
</head>
<body ng-app="myapp">
<div ng-controller="try as ctl">
<input ng-model="ctl.ticket.nombre">
<textarea ng-model="ctl.ticket.code"></textarea>
<button ng-click="ctl.send()">Enviar</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script>
var ws = new WebSocket("ws://localhost:2645/service");
ws.binaryType = "arraybuffer";
ws.onopen = function () {
console.log('connection is opened!!!');
};
ws.onmessage = function (evt) {
console.log(arrayBufferToString(evt.data))
};
ws.onclose = function () {
console.log("Connection is Closed...")
};
function arrayBufferToString(buffer) {
var arr = new Uint8Array(buffer);
var str = String.fromCharCode.apply(String, arr);
return decodeURIComponent(escape(str));
}
var app = angular.module('myapp', []);
app.controller('try', function () {
this.ticket= {nombre:'', estado:''}
this.send = () => {
var toSend= JSON.stringify(this.ticket);
ws.send(toSend);
}
});
</script>
</body>
</html>
then send a ZPL code from html(write this on textarea code);
^XA
^FO200,50^BY2^B3N,N,80,Y,N^FD0123456789^FS
^PQ1^XZ

Is there any way to display image in client browser without uploading it to server?

I am writing a simple "Book" create page in ASP.NET MVC. User can create book by filling title,year etc.. and selecting a cover image. When user press "Create" button Form sends image and data to Controller action called "Create" then I save image to disk and data to database.
But I want to display image when user select image by file dialog.To do this As far as I know I must upload image to server then display in client browser.But if a user cancels the "Create" operation after uploading image, the image will remain in the server's disk.So How can I deal with these temp images or Is there any way to display image in client browser without upload to server?
Due to security reasons, you will not be able to display the images to the users without uploading them to the server. Displaying images from file system is considered a security risk.
EDIT: To remove the unused images, you can create a thread to run a cleanup routine to which will delete them from the upload directory regularly.
Yes, using Silverlight, for example:
In Page.xaml:
<StackPanel x:Name="LayoutRoot" Background="White">
<Button x:Name="btn1" Content="Select image file">
<Image x:Name="img1">
</StackPanel>
and in Page.xaml.cs:
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
btn1.Click += new RoutedEventHandler(btn1_Click);
}
void btn1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
Stream s = ofd.File.OpenRead();
BitmapImage bi = new BitmapImage();
bi.SetSource(s);
img1.Source = bi;
s.Close();
}
}
}
Read more here.
Yes, you can using javascript
Javascript:
function showThumbnail(files){
for(var i=0;i<files.length;i++){
var file = files[i]
var imageType = /image.*/
if(!file.type.match(imageType)){
console.log("Not an Image");
continue;
}
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
thumbnail.appendChild(image)
var reader = new FileReader()
reader.onload = (function(aImg){
return function(e){
aImg.src = e.target.result;
};
}(image))
var ret = reader.readAsDataURL(file);
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
image.onload= function(){
ctx.drawImage(image,100,100)
}
}
}
var fileInput = document.getElementById("upload-image");
fileInput.addEventListener("change",function(e){
var files = this.files
showThumbnail(files)
},false)
HTML:
<input type="file" id="upload-image" multiple="multiple"></input>
<div id="thumbnail"></div>
You just need the input field and The div to display the thumbnail image, and on change for the input field will call showThumbnail function which will append img inside the "thumbnail" div.
You can do it with Simple javascript...
assign the selected image path.. to image tag prefixing the file://, n it works the way you want it to be

Resources