I have a feature request. The current flow is for the user to scan a code (not a QR code, not sure what it is, zxing will scan it), then scan the test card.
The client has asked for me allow the user to import the test from the library. So we need to be able to scan the code off an image.
Is it possible to do this in zxing or am I forced to use the camera / feature is not possible?
Thanks!
Here is my solution. I had to downsize the image, and inver the colors for it to work with zxing. I might add a convert to gray scale, but not today..
public static String scanDataMatrixImage(Bitmap bitmap) {
bitmap = doInvert(bitmap);
double scaling = getScaling(bitmap);
Bitmap resized;
if(scaling>0) {
resized = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * scaling), (int) (bitmap.getHeight() * scaling), true);
}
else{
resized = bitmap;
}
String contents = null;
int[] intArray = new int[resized.getWidth() * resized.getHeight()];
//copy pixel data from the Bitmap into the 'intArray' array
resized.getPixels(intArray, 0, resized.getWidth(), 0, 0, resized.getWidth(), resized.getHeight());
LuminanceSource source = new RGBLuminanceSource(resized.getWidth(), resized.getHeight(), intArray);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
MultiFormatReader reader = new MultiFormatReader();
try
{
Result result = reader.decode(binaryBitmap);
contents = result.getText();
} catch (
Exception e
)
{
Log.e("QrTest", "Error decoding barcode", e);
}
return contents;
}
private static double getScaling(Bitmap bitmap){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int smallest = width;
if(smallest > height){
smallest = height;
}
double ratio = 200.0/smallest;
return ratio;
}
public static Bitmap doInvert(Bitmap src) {
// create new bitmap with the same settings as source bitmap
Bitmap bmOut = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
// color info
int A, R, G, B;
int pixelColor;
// image size
int height = src.getHeight();
int width = src.getWidth();
// scan through every pixel
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// get one pixel
pixelColor = src.getPixel(x, y);
// saving alpha channel
A = Color.alpha(pixelColor);
// inverting byte for each R/G/B channel
R = 255 - Color.red(pixelColor);
G = 255 - Color.green(pixelColor);
B = 255 - Color.blue(pixelColor);
// set newly-inverted pixel to output image
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final bitmap
return bmOut;
}
Related
I am trying to image flip and image filter But I have a problem with that When I put a filter on the image then when I flip the image the filter is removed
public void Flipimg(View v1){
img1.setImageBitmap(fliph(scaledBitmap));
}
public Bitmap fliph(Bitmap bms){
Matrix mat = new Matrix();
mat.setScale(-1, 1);
Bitmap bit1=Bitmap.createBitmap( bms, 0, 0, bms.getWidth(), bms.getHeight(), mat, true);
return bit;
public void Filterimg(View v2){
img1.setImageBitmap(applyGreyscaleEffect(scaledBitmap));
}
public Bitmap applyGreyscaleEffect(Bitmap src) {
final double GS_RED = 0.299;
final double GS_GREEN = 0.587;
final double GS_BLUE = 0.114;
Bitmap bmOut = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
int A, R, G, B;
int pixel;
int width = src.getWidth();
int height = src.getHeight();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
R = G = B = (int) (GS_RED * R + GS_GREEN * G + GS_BLUE * B);
bmOut.setPixel(x, y, Color.argb(A, R, G, B));}
}
return bmOut;
looking images THIS image flip
THIS image apply filter
If you'd like to apply effects sequentially, get current bitmap on the ImageView via BitmapDrawable.
public void Flipimg(View v1)
{
//img1.setImageBitmap(fliph(scaledBitmap));
Bitmap currentBitmap = ((BitmapDrawable) img1.getDrawable()).getBitmap();
img1.setImageBitmap(fliph(currentBitmap));
}
public void Filterimg(View v2)
{
//img1.setImageBitmap(applyGreyscaleEffect(scaledBitmap));
Bitmap currentBitmap = ((BitmapDrawable) img1.getDrawable()).getBitmap();
img1.setImageBitmap(applyGreyscaleEffect(currentBitmap));
}
when i load image from gallery to the imageview, it can't recognize the height and width of the image, but i load the image from drawable , it recognize the height and width of the image. please tell where i made a mistake?
here i attached the code below,
Blockquote
source = BitmapFactory.decodeResource(getResources(),R.id.image);
mRed = findViewById(R.id.red);
mRed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bitmap = applyColorFilterEffect(source, 255, 0, 0);
imageView.setImageBitmap(bitmap);
}
});
Blockquote
public Bitmap applyColorFilterEffect(Bitmap src, double red, double green, double blue) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
//get pixel color
pixel = src.getPixel(x, y);
// apply filtering on each channel R, G, B
A = Color.alpha(pixel);
R = (int) (Color.red(pixel) * red);
G = (int) (Color.green(pixel) * green);
B = (int) (Color.blue(pixel) * blue);
// set new color pixel to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
i hava done with get grayscale value, but i don't know how to use function to convert the grayscale to be binary image. Please help me, here my function code:
public Bitmap toBinary(Bitmap bmpOriginal) {
int width, height, threshold;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
threshold = 127;
final Bitmap bmpBinary = null;
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get one pixel color
int pixel = bmpOriginal.getPixel(x, y);
//get grayscale value
int gray = (int)(pixel & 0xFF);
//get binary value
if(gray < threshold){
bmpBinary.setPixel(x, y, 0);
} else{
bmpBinary.setPixel(x, y, 255);
}
}
}
return bmpBinary;
}
here my full code:
public class MainActivity extends Activity {
ImageView img;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//convert imageview to bitmap
img =(ImageView) findViewById(R.id.imageView1);
BitmapDrawable drawable = (BitmapDrawable) img.getDrawable();
final Bitmap imgbitmap = drawable.getBitmap();
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//convert bitmap to grayscale
Bitmap imgnew;
imgnew = toGrayscale(imgbitmap);
//convert to binary
imgnew = toBinary(imgnew);
//convert bitmap to imageview
ImageView imgbit;
imgbit = (ImageView) findViewById(R.id.imageView2);
imgbit.setImageBitmap(imgnew);
}
});
}
public Bitmap toGrayscale(Bitmap bmpOriginal){
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
public Bitmap toBinary(Bitmap bmpOriginal) {
int width, height, threshold;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
threshold = 127;
final Bitmap bmpBinary = null;
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get one pixel color
int pixel = bmpOriginal.getPixel(x, y);
//get grayscale value
int gray = (int)(pixel & 0xFF);
//get binary value
if(gray < threshold){
bmpBinary.setPixel(x, y, 0);
} else{
bmpBinary.setPixel(x, y, 255);
}
}
}
return bmpBinary;
}
}
First, you get a NullReferenceException because bmpBinary is NULL.
Second, to get one Color chanel you can use int red = Color.red(pixel);
Third, to set a pixel white use bmpBinary.setPixel(x, y, 0xFFFFFFFF);
I modified your code a bit:
public Bitmap toBinary(Bitmap bmpOriginal) {
int width, height, threshold;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
threshold = 127;
Bitmap bmpBinary = Bitmap.createBitmap(bmpOriginal);
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get one pixel color
int pixel = bmpOriginal.getPixel(x, y);
int red = Color.red(pixel);
//get binary value
if(red < threshold){
bmpBinary.setPixel(x, y, 0xFF000000);
} else{
bmpBinary.setPixel(x, y, 0xFFFFFFFF);
}
}
}
return bmpBinary;
}
An even better way is not to use just the value of one color chanel but a weighted average of red green and blue for example:
int gray = (int)(red * 0.3 + green * 0.59 + blue * 0.11);
I created an example image with brightness adjusted in Android. I used Bitmap to adjust the brightness but it takes a very long time to run. Instead, I want to set the image brightness in Android using OpenCV.
This is my example code, but it only changes the colour of the image:
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.a001);
int width = bmp.getWidth();
int height = bmp.getHeight();
Mat mRgba = new Mat(width, height, CvType.CV_8UC1);
Utils.bitmapToMat(bmp, mRgba);
Mat mRay = new Mat();
Imgproc.cvtColor(mRgba, mRay, Imgproc.COLOR_BGRA2RGB, 4);
Utils.matToBitmap(mRay, bmp);
mImageview_01.setImageBitmap(bmp);
[Update]
I try add code, but it error
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.a001);
int width = bmp.getWidth();
int height = bmp.getHeight();
Mat mRgba = new Mat(width, height, CvType.CV_8UC1);
Utils.bitmapToMat(bmp, mRgba);
Mat mRay = new Mat();
Imgproc.cvtColor(mRgba, mRay, Imgproc.COLOR_BGRA2RGB, 4);
/*
* Use Adaptive Thresholding on the grayscaled Mats crop -> threshed Mat
* src, Mat dst, double maxValue, int adaptiveMethod, int thresholdType,
* int blockSize, double C
*/
Imgproc.adaptiveThreshold(threshed, threshed, 255,
Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 15, 8);
Utils.matToBitmap(mRay, bmp);
mImageview_01.setImageBitmap(bmp);
[Error]
CvException [org.opencv.core.CvException: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/thresh.cpp:796: error: (-215) src.type() == CV_8UC1 in function void cv::adaptiveThreshold(cv::InputArray, cv::OutputArray, double, int, int, int, double)
Pls view examples of what I'm trying to do here.
There is many fast and easy ways to adjust a bitmap brightness, such as ColorMatrix or RenderScript. But if you still considered to use OpenCV that's the way :
private Bitmap changeBrightness(Bitmap bmp, int value){
Mat src = new Mat(bmap.getHeight(),bmap.getWidth(), CvType.CV_8UC1);
Utils.bitmapToMat(bmap,src);
src.convertTo(src,-1,1,value);
Bitmap result = Bitmap.createBitmap(src.cols(),src.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(src,result);
return result;
}
check the example given at Increase/Decrease Brightness of Image
pls see this
int brightness;
SeekBar seekBarBrightness=(SeekBar)findViewById(R.id.seekBar1);
seekBarBrightness.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar arg0) {
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
}
#Override
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) {
Bitmap newBitMap = doBrightness(bitMap,progress);
imageView.setImageBitmap(newBitMap);
}
});
public static Bitmap doBrightness(Bitmap src, int value)
{
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for (int x = 0; x < width; ++x)
{
for (int y = 0; y < height; ++y)
{
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// increase/decrease each channel
R += value;
if (R > 255)
{
R = 255;
} else if (R < 0)
{
R = 0;
}
G += value;
if (G > 255)
{
G = 255;
} else if (G < 0)
{
G = 0;
}
B += value;
if (B > 255)
{
B = 255;
} else if (B < 0)
{
B = 0;
}
// apply new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final image
return bmOut;
}
How can i to get color/alpha of pixel from Sprite in andengine without creating any additional Bitmap?
I solved this problem by using this function
private void loadObjectsMask()
{
InputStream in = null;
Bitmap maskForObjects=null;
try {
final BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
decodeOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
in = GameActivity.this.getAssets().open("images/" + BACKGROUND_PATH + getObjectImgFile());
maskForObjects = BitmapFactory.decodeStream(in, null, decodeOptions);
} catch (final IOException e) {
} finally {
StreamUtils.close(in);
}
if (maskForObjects != null)
{
objectsMask=new byte[maskForObjects.getWidth()][maskForObjects.getHeight()];
for(int pw=0;pw<maskForObjects.getWidth();++pw)
{
for(int ph=0;ph<maskForObjects.getHeight();++ph)
{
objectsMask[pw][ph]=(byte)(Color.alpha(maskForObjects.getPixel(pw, ph))==0?0:1);
}
}
maskForObjects.recycle();
System.out.printf("Bitmap size %d %d\n", maskForObjects.getWidth(),maskForObjects.getHeight());
}
else System.out.printf("Bitmap size error\n");
}
have a look this method, this method are used to effect on each pix
public Bitmap invert(Bitmap src) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
// get color on each channel
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// set new pixel color to output image
bmOut.setPixel(x, y, Color.argb(A, 255-R, 255-G, 255-B));
}
}
// return final image
return bmOut;
}
To convert Gray Scale
public static Bitmap toGrayscale(Bitmap bmpOriginal)
{
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}