I am referencing this to generate code39 format 1D barcode using Zxing library.
Generate barcode image in Android application
I can generate the barcode. Because i will have three different codes to show in the UI.
Three different codes can have different length like below:
String barcode1_data = "1234567EA";
String barcode2_data = "1234567891012388";
String barcode3_data = "123456789000100";
bitmap1 = encodeAsBitmap2(barcode1_data, BarcodeFormat.CODE_39, 800, 120);
bitmap2 = encodeAsBitmap2(barcode2_data, BarcodeFormat.CODE_39, 1200, 150);
bitmap3 = encodeAsBitmap2(barcode3_data, BarcodeFormat.CODE_39, 1200, 150);
The result UI like this:
I would like to have the three different barcodes to have the same height, and also the width depends on the characters. In my sample code, i hard coded, but i want it to be dynamic. Is there any rule to calculate the height and width?
Since you're creating 1D barcode, how about download a free barcode TTF, and use it on TextView ?
I think it's easy to adjust TextView's width & height.
Related
I am kind of stuck with this problem, and I know there are so many questions about it on stack overflow but in my case. Nothing gives the expected result.
The Context:
Am using Android OpenCV along with Tesseract so I can read the MRZ area in the passport. When the camera is started I pass the input frame to an AsyncTask, the frame is processed, the MRZ area is extracted succesfully, I pass the extracted MRZ area to a function prepareForOCR(inputImage) that takes the MRZ area as gray Mat and Will output a bitmap with the thresholded image that I will pass to Tesseract.
The problem:
The problem is while thresholding the Image, I use adaptive thresholding with blockSize = 13 and C = 15, but the result given is not always the same depending on the lighting of the image and the conditions in general from which the frame is taken.
What I have tried:
First I am resizing the image to a specific size (871,108) so the input image is always the same and not dependant on which phone is used.
After resizing, I try with different BlockSize and C values
//toOcr contains the extracted MRZ area
Bitmap toOCRBitmap = Bitmap.createBitmap(bitmap);
Mat inputFrame = new Mat();
Mat toOcr = new Mat();
Utils.bitmapToMat(toOCRBitmap, inputFrame);
Imgproc.cvtColor(inputFrame, inputFrame, Imgproc.COLOR_BGR2GRAY);
TesseractResult lastResult = null;
for (int B = 11; B < 70; B++) {
for (int C = 11; C < 70; C++){
if (IsPrime(B) && IsPrime(C)){
Imgproc.adaptiveThreshold(inputFrame, toOcr, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, B ,C);
Bitmap toOcrBitmap = OpenCVHelper.getBitmap(toOcr);
TesseractResult result = TesseractInstance.extractFrame(toOcrBitmap, "ocrba");
if (result.getMeanConfidence()> 70) {
if (MrzParser.tryParse(result.getText())){
Log.d("Main2Activity", "Best result with " + B + " : " + C);
return result;
}
}
}
}
}
Using the code below, the thresholded result image is a black on white image which gives a confidence greater than 70, I can't really post the whole image for privacy reasons, but here's a clipped one and a dummy password one.
Using the MrzParser.tryParse function which adds checks for the character position and its validity within the MRZ, am able to correct some occurences like a name containing a 8 instead of B, and get a good result but it takes so much time, which is normal because am thresholding almost 255 images in the loop, adding to that the Tesseract call.
I already tried getting a list of C and B values which occurs the most but the results are different.
The question:
Is there a way to define a C and blocksize value so that it s always giving the same result, maybe adding more OpenCV calls so The input image like increasing contrast and so on, I searched the web for 2 weeks now I can't find a viable solution, this is the only one that is giving accurate results
You can use a clustering algorithm to cluster the pixels based on color. The characters are dark and there is a good contrast in the MRZ region, so a clustering method will most probably give you a good segmentation if you apply it to the MRZ region.
Here I demonstrate it with MRZ regions obtained from sample images that can be found on the internet.
I use color images, apply some smoothing, convert to Lab color space, then cluster the a, b channel data using kmeans (k=2). The code is in python but you can easily adapt it to java. Due to the randomized nature of the kmeans algorithm, the segmented characters will have label 0 or 1. You can easily sort it out by inspecting cluster centers. The cluster-center corresponding to characters should have a dark value in the color space you are using.
I just used the Lab color space here. You can use RGB, HSV or even GRAY and see which one is better for you.
After segmenting like this, I think you can even find good values for B and C of your adaptive-threshold using the properties of the stroke width of the characters (if you think the adaptive-threshold gives a better quality output).
import cv2
import numpy as np
im = cv2.imread('mrz1.png')
# convert to Lab
lab = cv2.cvtColor(cv2.GaussianBlur(im, (3, 3), 1), cv2.COLOR_BGR2Lab)
im32f = np.array(im[:, :, 1:3], dtype=np.float32)
k = 2 # 2 clusters
term_crit = (cv2.TERM_CRITERIA_EPS, 30, 0.1)
ret, labels, centers = cv2.kmeans(im32f.reshape([im.shape[0]*im.shape[1], -1]),
k, None, term_crit, 10, 0)
# segmented image
labels = labels.reshape([im.shape[0], im.shape[1]]) * 255
Some results:
I have been working in printing an image via bluetooth printer. When I test it for
text printing it works perfectly. But when it comes to image, prints only string characters.
I have converted the layout into bitmap. And saved it into sd card. Do I need to convert the bitmap into
something that supports for printer. Am using "ZEBRA EZ320" printer for my application.
I have used the following code to convert the layout into bitmap,
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
I found solution to my problem.
Bitmap localBitmap=BitmapFactory.decodeResource(getResources(), image);
BluetoothConnection myConn = new BluetoothConnection(macaddr);
ZebraPrinter myPrinter = new ZebraPrinterCpcl(myConn);
myConn.open();
new ZebraPrinterLegacyDelegator(myPrinter).getGraphicsUtil().printImage(localBitmap, 0, 0, -1, -1, false);
// to reduce extra space
myConn.write("! UTILITIES\r\nIN-MILLIMETERS\r\nSETFF 10 2\r\nPRINT\r\n".getBytes());
myConn.close();
The code mentioned in the above answer uses ZebraPrinterLegacyDelegator, which is deprecated.
Use the following code,
InputStream inputStream = assetManager.open("printing/ic_launcher.png");
ZebraImageI zebraImageI = ZebraImageFactory.getImage(BitmapFactory.decodeStream(inputStream));
zebraPrinter.printImage(zebraImageI, 250, 0, 0, -1, false);
Zebra Printer instance can be created as follow,
zebraPrinter = ZebraPrinterFactory.getInstance(printerConnection);
printImage arguments are as follows,
image - the image to be printed.
x - horizontal starting position in dots.
y - vertical starting position in dots.
width - desired width of the printed image. Passing a value less than 1 will preserve original width.
height - desired height of the printed image. Passing a value less than 1 will preserve original height.
insideFormat - boolean value indicating whether this image should be printed by itself (false), or is part of a format being written to the connection (true).
And also to address your alignment problems change the x value to move the image to your convenient place.
I am comparing 2 similar images and would like to see if both are similar .Currently I used the code:
public void foo(Bitmap bitmapFoo) {
int[] pixels;
int height = bitmapFoo.getHeight();
int width = bitmapFoo.getWidth();
pixels = new int[height * width];
bitmapFoo.getPixels(pixels, 0, width, 1, 1, width - 1, height - 1);
}
and I call the function : foo(img1) where :
img1=(Bitmap)data.getExtras().get("data");
I would like to know how to get the above getpixel,I tried assigning it to variable but did not work .Should it have a return type ?? and in format it is ?
And also how do I compare 2 images??
Also both the images may be of different dimensions based on the mobile camera the snapshot is taken from .
Also can it recognize if the same image is shot in the morning and night ???
Thanks in Advance.
This code will compare pixel from base image with other image.
If both pixel at location (x,y) are same then add same pixel in result image without change. Otherwise it modifies that pixel and add to our result image.
In case of baseline image height or width is larger than other image then it will add red color for extra pixel which is not available in other images.
Both image file format should be same for comparison.
Code will use base image file format to create resultant image file and resultant image contains highlighted portion where difference observed.
Here is a Link To Code with sample example attached.
If you want to copy the pixels of the bitmap to a byte array, the easiest way is:
int height = bitmapFoo.getHeight();
int width = bitmapFoo.getWidth();
pixels = new int[height * width];
bitmapFoo.copyPixelsToBuffer(pixels);
See the documentation
I should warn you that you will have to handle this with care, any other way you will get OutOfMemoryError.
To get All Pixels
bitmapFoo.copyPixelsToBuffer(pixels);
or
bitmapFoo.getPixels(pixels, 0, width, 0, 0, width, height);
To get One Pixel
The two arguments must be two integers within the range [0, getWidth()-1] and [0, getHeight()-1]
int pix = bitmapFoo.getPixel(x, y);
Suppose I'm uploading two or more than two pics in some Framelayout. Hereby I'm uploading three pics with a same person in three different position in all those three pictures. Then what image processing libraries in Android or java or Native's are available to do something as shown in the pic.
I would like to impose multiple pictures on each other.
Something like these:-
One idea is to :
Do some layering in all those pictures and find mismatching areas in the pics and merge them.
How one can merge multiple picture with other? By checking the di-similarity and merge with each other?
Are there any Third party Api's or some Photoshop service which can help me in doing these kinda image processing?
In this case you are not just trying to combine the images. You really want to combine a scene containing the same object in different positions.
Therefore, it is not just a simple combination or an alpha compositve where the color of a given pixel in the output image is the sum of the value of this pixel in each image, divided by the number of images.
In this case, you might do:
Determine the scene background analysing the pixels that do not change considering multiple images.
Begin with the output image being just the background.
For each image, remove the background to get the desired object and combine it with the output image.
There is a Marvin plug-in to perform this task, called MergePhoto. The program below use that plug-in to combine a set of parkour photos.
import marvin.image.MarvinImage;
import marvin.io.MarvinImageIO;
import marvin.plugin.MarvinImagePlugin;
import marvin.util.MarvinPluginLoader;
public class MergePhotosApp {
public MergePhotosApp(){
// 1. load images 01.jpg, 02.jpg, ..., 05.jpg into a List
List<MarvinImage> images = new ArrayList<MarvinImage>();
for(int i=1; i<=5; i++){
images.add(MarvinImageIO.loadImage("./res/0"+i+".jpg"));
}
// 2. Load plug-in and process the image
MarvinImagePlugin merge = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.combine.mergePhotos");
merge.setAttribute("threshold", 38);
// 3. Process the image list and save the output
MarvinImage output = images.get(0).clone();
merge.process(images, output);
MarvinImageIO.saveImage(output, "./res/merge_output.jpg");
}
public static void main(String[] args) {
new MergePhotosApp();
}
}
The input images and the output image are shown below.
I don't know if this will qualify to be in your definition of "natives", but there is the following .NET library that could help: http://dynamicimage.apphb.com/
If the library itself can give you want you want, then depending on your architecture you could set up a small ASP.NET site to do the image manipulation on the server.
Check the accepted answer here.
In above link there is merging of two images which is done by openCV sdk.
If you dont want to use openCV and just want to try with your self then you will have to play little with framlayout and with three imageview. Give options to user to select specific part of the image to show for all three images. So the selected part will be shown of the selected image. on this way you will get the result like above what you have said.
Hope you got my point. If not then let me know.
Enjoy coding... :)
You can overlay the images using openCV you can check at OpenCV and here or here
// Read the main background image
cv::Mat image= cv::imread("Background.png");
// Read the mans character image to be placed
cv::Mat character= cv::imread("character.png");
// define where you want to place the image
cv::Mat newImage;
//The 10,10 are the initial coordinates in pixels
newImage= image(cv::Rect(10,10,character.cols,character.rows));
// add it to the background, The 1 is the aplha values
cv::addWeighted(newImage,1,character,1,0,newImage);
// show result
cv::namedWindow("with character");
cv::imshow("with character",image);
//Write Image
cv::imwrite("output.png", newImage);
or you can create it as a watermark effect
Or you can try it in java like merging two images
try using this class
public class MergeImages {
public static void main(String[] args) {
File inner = new File("Inner.png");
File outter = new File("Outter.png");
try {
BufferedImage biInner = ImageIO.read(inner);
BufferedImage biOutter = ImageIO.read(outter);
System.out.println(biInner);
System.out.println(biOutter);
Graphics2D g = biOutter.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
int x = (biOutter.getWidth() - biInner.getWidth()) / 2;
int y = (biOutter.getHeight() - biInner.getHeight()) / 2;
System.out.println(x + "x" + y);
g.drawImage(biInner, x, y, null);
g.dispose();
ImageIO.write(biOutter, "PNG", new File("Outter.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
i am trying to give a Photoshop posterization effect to imageview.here is a normal image.
after applying posterization effect it should look like this,this effect is taken from pixlr image editor
I want exact effect programmatically.
what I have tried is, I am trying to get similar effect with SaturationFilter kind of effect, as I am not able to find posterization method for android.
here is my function http://pastie.org/8007887
and resulting image is,as below which is not looking similar to Photoshop posterized effect, I have tried passing several saturation level,but no luck.i hope some one will guide me in a proper way.
found some way, http://developer.android.com/reference/android/media/effect/EffectFactory.html here is a guidline for posterization effect,and that is applicable for android API level 14,what about device which use API level <14?
There is a good library available named JHLabs' Java Image Processing.
It has lots of image processing filters available. I also use that library in my application. It is very compatible with Android also.
You can also download source code and run sample application.
JAR Download : http://www.jhlabs.com/ip/filters/Filters.zip
You could use the following
1. Android + Open CV
2. Android + Openframeworks
http://www.openframeworks.cc/setup/android-eclipse/
check out sample at
https://github.com/nkint/ofxPosterize
You can apply such effect by playing on different source code available
I would suggest you to go with this url and check the different effect https://xjaphx.wordpress.com/learning/tutorials/
The most relevant function i could see is mentioned below, try to modify it according to your need
int width = mImage.getWidth();
int height = mImage.getHeight();
int[] pixels = new int[width * height];
mImage.getPixels(pixels, 0, width, 0, 0, width, height);
for(int x = 0; x < pixels.length; ++x) {
pixels[x] = (pixels[x] == fromColor) ? targetColor : pixels[x];
}
Bitmap newImage = Bitmap.createBitmap(width, height, mImage.getConfig());
newImage.setPixels(pixels, 0, width, 0, 0, width, height);
return newImage;