Using zxing in Blackberry 5.0 - blackberry

I'm stucked when implementing Barcode scanning in Blackberry 5.0 SDK, since I'm look into deep search on the internet, and found no clue.
Then I started to write my own class to provide Barcode Scanning (using zxing core)
then I need to implements BitmapLuminanceSource (rim version not Android version)
public class BitmapLuminanceSource extends LuminanceSource {
private final Bitmap bitmap;
public BitmapLuminanceSource(Bitmap bitmap){
super(bitmap.getWidth(),bitmap.getHeight());
this.bitmap = bitmap;
}
public byte[] getRow(int y, byte[] row) {
//how to implement this method
return null;
}
public byte[] getMatrix() {
//how to implement this method
return null;
}
}

Well, the javadoc in LuminanceSource tells you what it returns. And you have implementations like PlanarYUVLuminanceSource in android/ that show you an example of it in action. Did you look at these at all?
The quick answer though is that both return one row of the image, or the entire image, as an array of luminance values. There is one byte value per pixel and it should be treated as an unsigned value.

I've solved this problem.
Here's the BitmapLuminanceSource implementation
import net.rim.device.api.system.Bitmap;
import com.google.zxing.LuminanceSource;
public class BitmapLuminanceSource extends LuminanceSource {
private final Bitmap bitmap;
private byte[] matrix;
public BitmapLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
int width = bitmap.getWidth();
int height = bitmap.getHeight();
this.bitmap = bitmap;
int area = width * height;
matrix = new byte[area];
int[] rgb = new int[area];
bitmap.getARGB(rgb, 0, width, 0, 0, width, height);
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = rgb[offset + x];
int luminance = (306 * ((pixel >> 16) & 0xFF) + 601
* ((pixel >> 8) & 0xFF) + 117 * (pixel & 0xFF)) >> 10;
matrix[offset + x] = (byte) luminance;
}
}
rgb = null;
}
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException(
"Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
int offset = y * width;
System.arraycopy(this.matrix, offset, row, 0, width);
return row;
}
public byte[] getMatrix() {
return matrix;
}
}
I added com.google.zxing (library for Barcode encode/decode) to my project

Related

Image printing with Epson compatible Thermal printer problem

I am using C# and write code for print contents for the Thermal ticket printer.
There are codes that people use for image print, and it indeed prints images, but something goes wrong. This is my code for image print class, it is widely using open source (I googled and found it, and people successfully implement this code to theirs without problem).
public static class ImagePrint
{
/// <summary>
/// Image convert to Byte Array
/// </summary>
/// <param name="LogoPath">Image Path</param>
/// <param name="printWidth">Image print Horizontal Length</param>
/// <returns></returns>
public static byte[] GetLogo(string LogoPath, int printWidth)
{
List<byte> byteList = new List<byte>();
if (!File.Exists(LogoPath))
return null;
BitmapData data = GetBitmapData(LogoPath, printWidth);
BitArray dots = data.Dots;
byte[] width = BitConverter.GetBytes(data.Width);
int offset = 0;
// Initialize Printer
byteList.Add(Convert.ToByte(Convert.ToChar(0x1B)));
byteList.Add(Convert.ToByte('#'));
// Line Spacing Adjust (24/180 inch)
byteList.Add(Convert.ToByte(Convert.ToChar(0x1B)));
byteList.Add(Convert.ToByte('3'));
byteList.Add((byte)24);
while (offset < data.Height)
{
byteList.Add(Convert.ToByte(Convert.ToChar(0x1B)));
byteList.Add(Convert.ToByte('*'));
byteList.Add((byte)33);
byteList.Add(width[0]);
byteList.Add(width[1]);
for (int x = 0; x < data.Width; ++x)
{
for (int k = 0; k < 3; ++k)
{
byte slice = 0;
for (int b = 0; b < 8; ++b)
{
int y = (((offset / 8) + k) * 8) + b;
int i = (y * data.Width) + x;
bool v = false;
if (i < dots.Length)
v = dots[i];
slice |= (byte)((v ? 1 : 0) << (7 - b));
}
byteList.Add(slice);
}
}
offset += 24;
byteList.Add(Convert.ToByte(0x0A));
}
// Return to normal line spacing (30/160 inch)
byteList.Add(Convert.ToByte(0x1B));
byteList.Add(Convert.ToByte('3'));
byteList.Add((byte)30);
return byteList.ToArray();
}
private static BitmapData GetBitmapData(string bmpFileName, int width)
{
using (var bitmap = (Bitmap)Bitmap.FromFile(bmpFileName))
{
var threshold = 127;
var index = 0;
double multiplier = width; // 이미지 width조정
double scale = (double)(multiplier / (double)bitmap.Width);
int xheight = (int)(bitmap.Height * scale);
int xwidth = (int)(bitmap.Width * scale);
var dimensions = xwidth * xheight;
var dots = new BitArray(dimensions);
for (var y = 0; y < xheight; y++)
{
for (var x = 0; x < xwidth; x++)
{
var _x = (int)(x / scale);
var _y = (int)(y / scale);
var color = bitmap.GetPixel(_x, _y);
var luminance = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
dots[index] = (luminance < threshold);
index++;
}
}
return new BitmapData()
{
Dots = dots,
Height = (int)(bitmap.Height * scale),
Width = (int)(bitmap.Width * scale)
};
}
}
private class BitmapData
{
public BitArray Dots
{
get;
set;
}
public int Height
{
get;
set;
}
public int Width
{
get;
set;
}
}
}
And I use this code like this on my code for image print:
string Image_File_Path = #"D:\TEST\TESTImage.bmp";
int Image_Size_I_Want = 100;
byte[] img = ImagePrint.GetLogo(Image_File_Path, Image_Size_I_Want);
port.Write(img, 0, img.Length);
You can see the result in the attached picture.
There are white space lines on the image.
This class automatically adds a line spacing command, but it seems does not work.
Please suggest any solution.
Using 'mike42/escpos-php' package in laravel
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
$tux = EscposImage::load(public_path()."\assets\img\path-to-file.jpg");
$printer->setJustification(Printer::JUSTIFY_CENTER);
$printer->bitImage($tux, 0);
$printer -> setJustification();

How do I convert ByteArray from ImageMetaData() to Bitmap?

I have this code:
Frame frame = mSession.update();
Camera camera = frame.getCamera();
...
bytes=frame.getImageMetadata().getByteArray(0);
System.out.println("Byte Array "+frame.getImageMetadata().getByteArray(0));
Bitmap bmp = BitmapFactory.decodeByteArray(bytes,0,bytes.length);
System.out.println(bmp);
When I print Bitmap, I get a null object. I'm trying to get the image from the camera, that's the reason I'm trying to convert byteArray to Bitmap. If there's an alternative way, it would also be helpful.
Thank You.
The ImageMetaData describes the background image, but does not actually contain the image itself.
If you want to capture the background image as a Bitmap, you should look at the computervision sample which uses a FrameBufferObject to copy the image to a byte array.
I've tried something similar. It works. But I don't recommend anyone to try this way. It takes time because of nested loops.
CameraImageBuffer inputImage;
final Bitmap bmp = Bitmap.createBitmap(inputImage.width, inputImage.height, Bitmap.Config.ARGB_8888);
int width = inputImage.width;
int height = inputImage.height;
int frameSize = width*height;
// Write Bytebuffer to byte[]
byte[] imageBuffer= new byte[inputImage.buffer.remaining()];
inputImage.buffer.get(imageBuffer);
int[] rgba = new int[frameSize];
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++) {
int r =imageBuffer[(i * width + j)*4 + 0];
int g =imageBuffer[(i * width + j)*4 + 1];
int b =imageBuffer[(i * width + j)*4 + 2];
rgba[i * width + j] = 0xff000000 + (b << 16) + (g << 8) + r;
}
}
bmp.setPixels(rgba, 0, width , 0, 0, width, height);
Bytebuffer is converted to rgba buffer, and is written to Bitmap. CameraImageBuffer is the class provided in computervision sample app.
You may not able to get bitmap using image metadata. Use below approach.Use onDrawFrame override method of surface view render.
#Override public void onDrawFrame(GL10 gl) {
int w = 1080;
int h = 1080;
int b[] = new int[w * (0 + h)];
int bt[] = new int[w * h];
IntBuffer ib = IntBuffer.wrap(b);
ib.position(0);
GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib);
for (int i = 0, k = 0; i < h; i++, k++) {
for (int j = 0; j < w; j++) {
int pix = b[i * w + j];
int pb = (pix >> 16) & 0xff;
int pr = (pix << 16) & 0x00ff0000;
int pix1 = (pix & 0xff00ff00) | pr | pb;
bt[(h - k - 1) * w + j] = pix1;
}
}
Bitmap mBitmap = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
runOnUiThread(new Runnable() {
#Override public void run() {
image_test.setImageBitmap(resizedBitmap);
}
});
}

conversion of an image to grayscale using fork and join framework java

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import javax.imageio.ImageIO;
import java.awt.*;
class Multicore1 extends RecursiveAction
{
private int[] msource;
private int mstart;
private int mlength;
private int[] mDestination;
private int window=15;
private BufferedImage mimage;
public Multicore1(int[] src,int start,int length,int[] dest,BufferedImage image)
{
msource=src;
mstart=start;
mlength=length;
mDestination=dest;
mimage=image;
}
protected void computeDirectly(BufferedImage Img)
{
int rgb;
int lum;
int grayval;
int rgbVal;
int x,y;
int sliding=(window-1)/2;
System.out.println(" mlenght valu is " + mlength);
System.out.println(" mstart valu is " + mstart);
float r=0; float g=0;float b=0;
int red=0,green=0,blue=0;
// the image after conversion doesnot seem to be properly converted to grayscal. please look upon my code if there is any mistake
for(x=mstart;x <(double) mstart+mlength; x++)
{
for( y=sliding; y <= sliding; y++)
{
int mindex = Math.min(Math.max(x+y , 0), msource.length - 1);
rgb=msource[mindex];
//rgbVal = msource.getRGB(x,y);
r = (float)((rgb & 0xff0000) >>16 ) ;
g = (float)((rgb & 0x00ff00)>> 8);
b = (float)((rgb & 0x0000ff) >>0 ) ;
}
lum=(int) Math.round(0.2126*r+0.7152*g+0.0722*b);
grayval=(lum<<16)|(lum<<8)|lum;
mDestination[x] =(grayval);
}
}
protected static int sThreshold = 10000;
#Override
protected void compute() {
if (mlength < sThreshold) {
computeDirectly(mimage);
return;
}
int split = mlength / 2;
invokeAll(new Multicore1(msource, mstart, split, mDestination,mimage),
new Multicore1(msource, mstart + split, mlength - split,
mDestination,mimage));
}
public static void main(String args[]) throws Exception
{
BufferedImage image=ImageIO.read(new File("xyz.jpg"));
int w=image.getWidth();
int h=image.getHeight();
BufferedImage convertedimg=grayscale(w,h,image);
String dstName = "Gray.jpg";
File dstFile = new File(dstName);
ImageIO.write(convertedimg,"jpg",dstFile);
}
public static BufferedImage grayscale(int w,int h,BufferedImage image)
{
int[] src=image.getRGB(0, 0, w, h, null, 0, w);
int[] dst=new int[src.length];
System.out.println("hello");
System.out.println("Array size is " + src.length);
System.out.println("Threshold is " + sThreshold);
Multicore1 m1=new Multicore1(src,0,src.length,dst,image);
ForkJoinPool pool=new ForkJoinPool();
long starttime=System.currentTimeMillis();
pool.invoke(m1);
long endtime=System.currentTimeMillis();
System.out.println("Time took:" +(endtime-starttime));
BufferedImage dstimage=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
//Color c=new Color(0,0,0);
dstimage.setRGB(0, 0, w, h, dst, 0, w);
//dstimage.setRGB(0,0,c.getRGB());
return dstimage;
}
}
grayval**=*(0xff000000)*|**(lum<<16)|(lum<<8)|lum;
You need to apply a mask before you move the bits.

Improve javaFx processing performance

I'm working on Image processing with javaFx. I think that my code is not enouth efficient (With HD images, refresh is very slow). Because I do a for on each pixel of my image everytime I have to refresh it. But I don't know how to do differently.
So I need help to improve the performance of my processing.
This is my code :
import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Slider;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Example extends Application {
private Image src;
private WritableImage dest;
private int width;
private int height;
int value = 0;
#Override
public void start(Stage stage) {
AnchorPane root = new AnchorPane();
initImage(root);
Scene scene = new Scene(root);
stage.setTitle("Demo processing");
stage.setResizable(false);
stage.setScene(scene);
stage.show();
}
private void initImage(AnchorPane root) {
src = new Image(
"http://mikecann.co.uk/wp-content/uploads/2009/12/ScreenHunter_02-Dec.-10-19.41-1024x484.jpg");
width = (int) src.getWidth();
height = (int) src.getHeight();
root.setPrefSize(800, 800 + 50);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setPrefHeight(600);
scrollPane.setPrefWidth(1000);
dest = new WritableImage(width, height);
ImageView destView = new ImageView(dest);
scrollPane.setContent(destView);
root.getChildren().add(scrollPane);
AnchorPane.setTopAnchor(scrollPane, 0.0);
Slider slider = new Slider(0, 255, 1);
slider.setPrefSize(800, 50);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
slider.setSnapToTicks(true);
slider.setMajorTickUnit(1.0);
slider.setMinorTickCount(0);
slider.setLayoutY(700);
slider.valueProperty().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable o) {
value = (int) ((DoubleProperty) o).get();
color();
}
});
root.getChildren().add(slider);
color();
}
private void color() {
PixelReader reader = src.getPixelReader();
PixelWriter writer = dest.getPixelWriter();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Color color = reader.getColor(x, y);
double red = (double) value * x * y / (width * height) / 255;
double green = color.getGreen();
double blue = (double) value * ((width * height) - x * y)
/ (width * height) / 255;
writer.setColor(x, y, Color.color(red, green, blue));
}
}
}
public static void main(String[] args) {
launch(args);
}
}
And this is with a full HD image :
src = new Image(
"http://www.freedomwallpaper.com//nature-wallpaper-hd/hd_sunshine_hd.jpg");
Getitng color of each pixel in loop is too slow. So, get entire pixels first, and change colors, finally wirte changed colors with PixelWriter.
Like this
private void color() {
PixelReader reader = src.getPixelReader();
WritablePixelFormat<IntBuffer> format = WritablePixelFormat.getIntArgbInstance();
int[] pixels = new int[width * height]; // Buffer for all pixels
reader.getPixels(0, 0, width, height, format, pixels, 0, width); // get all pixels by argb format
int alpha = 0xFF << 24;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int index = x + y * width;
int argb = pixels[index];
int red = value * x * y / (width * height);
int green = (argb >> 8) & 0xFF;
int blue = value * ((width * height) - x * y)
/ (width * height);
int newArgb = alpha | (red << 16) | (green << 8) | blue;
pixels[index] = newArgb;
}
}
PixelWriter writer = dest.getPixelWriter();
writer.setPixels(0, 0, width, height, format, pixels, 0, width); // write entire image
}

How to change color of image in JavaFX

I have a PNG image like this:
I want to change image to something like this:
How can I do this in JavaFX?
As you don't care if it is a vector shape or a bitmap, I'll just outline solutions using a bitmap here. If you actually wanted a vector shape, I believe you would need to work with vector input to get a good result.
Use a ColorAdjust effect with the brightness set to minimum (-1).
Cache the result for SPEED.
Here is a sample which creates a shadow outline of an image:
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.*;
import javafx.stage.Stage;
public class Shadow extends Application {
#Override
public void start(Stage stage) throws Exception {
ImageView imageView = new ImageView(
new Image(
"http://i.stack.imgur.com/jbT1H.png"
)
);
ColorAdjust blackout = new ColorAdjust();
blackout.setBrightness(-1.0);
imageView.setEffect(blackout);
imageView.setCache(true);
imageView.setCacheHint(CacheHint.SPEED);
stage.setScene(new Scene(new Group(imageView)));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}
Here is another sample which adjusts the color of an image, hover over smurfette to make her blush.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Shadow extends Application {
#Override
public void start(Stage stage) throws Exception {
Image image = new Image(
"http://icons.iconarchive.com/icons/designbolts/smurfs-movie/128/smurfette-icon.png"
);
ImageView imageView = new ImageView(image);
imageView.setClip(new ImageView(image));
ColorAdjust monochrome = new ColorAdjust();
monochrome.setSaturation(-1.0);
Blend blush = new Blend(
BlendMode.MULTIPLY,
monochrome,
new ColorInput(
0,
0,
imageView.getImage().getWidth(),
imageView.getImage().getHeight(),
Color.RED
)
);
imageView.effectProperty().bind(
Bindings
.when(imageView.hoverProperty())
.then((Effect) blush)
.otherwise((Effect) null)
);
imageView.setCache(true);
imageView.setCacheHint(CacheHint.SPEED);
stage.setScene(new Scene(new Group(imageView), Color.AQUA));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}
The below code will replace one pixel color with another. If you run that multiple times over your original image replacing gray scale values with color values you should be set.
To save memory you might want to adapt the code to reuse the writeable image for each loop.
/**
* reColor the given InputImage to the given color
* inspired by https://stackoverflow.com/a/12945629/1497139
* #param inputImage
* #param oldColor
* #param newColor
* #return reColored Image
*
*/
public static Image reColor(Image inputImage, Color oldColor, Color newColor) {
int W = (int) inputImage.getWidth();
int H = (int) inputImage.getHeight();
WritableImage outputImage = new WritableImage(W, H);
PixelReader reader = inputImage.getPixelReader();
PixelWriter writer = outputImage.getPixelWriter();
int ob=(int) oldColor.getBlue()*255;
int or=(int) oldColor.getRed()*255;
int og=(int) oldColor.getGreen()*255;
int nb=(int) newColor.getBlue()*255;
int nr=(int) newColor.getRed()*255;
int ng=(int) newColor.getGreen()*255;
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) {
int argb = reader.getArgb(x, y);
int a = (argb >> 24) & 0xFF;
int r = (argb >> 16) & 0xFF;
int g = (argb >> 8) & 0xFF;
int b = argb & 0xFF;
if (g==og && r==or && b==ob) {
r=nr;
g=ng;
b=nb;
}
argb = (a << 24) | (r << 16) | (g << 8) | b;
writer.setArgb(x, y, argb);
}
}
return outputImage;
}
I tried Wolfgang's reColor method above, but when I was trying to just recolor an image where I was trying to change all white pixels to another color, the result was always off and in many cases it wouldn't replace the colors at all, defaulting them to flat black for a variety of different colors that I tried.
So after figuring out what his code was doing, I came up with this method that actually does a one-for-one color pixel replacement and it works quite well.
import javafx.scene.paint.Color;
import javafx.scene.image.*;
private static Image reColor(Image inputImage, Color sourceColor, Color finalColor) {
int W = (int) inputImage.getWidth();
int H = (int) inputImage.getHeight();
WritableImage outputImage = new WritableImage(W, H);
PixelReader reader = inputImage.getPixelReader();
PixelWriter writer = outputImage.getPixelWriter();
float ocR = (float) sourceColor.getRed();
float ocG = (float) sourceColor.getGreen();
float ocB = (float) sourceColor.getBlue();
float ncR = (float) finalColor.getRed();
float ncG = (float) finalColor.getGreen();
float ncB = (float) finalColor.getBlue();
java.awt.Color oldColor = new java.awt.Color(ocR, ocG, ocB);
java.awt.Color newColor = new java.awt.Color(ncR, ncG, ncB);
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) {
int argb = reader.getArgb(x, y);
java.awt.Color pixelColor = new java.awt.Color(argb, true);
writer.setArgb(x, y,
pixelColor.equals(oldColor) ?
newColor.getRGB() :
pixelColor.getRGB());
}
}
return outputImage;
}

Resources