Android Studio How to read image file in OpenCV using resources? - android

I am trying to read image file using OpenCV Imgcodecs.imread(img) but the image Mat is always empty, I'm using this code:
package com.halocdz.qreagle;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.QRCodeDetector;
public class MainActivity extends AppCompatActivity {
TextView detectedData_text;
TextView detectStatus_text;
static
{
if (!OpenCVLoader.initDebug())
Log.e("OpenCv", "Unable to load OpenCV");
else
Log.d("OpenCv", "OpenCV loaded");
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize
detectStatus_text = (TextView)findViewById(R.id.detectStatus_text);
detectedData_text = (TextView)findViewById(R.id.detectedData_text);
}
#SuppressLint("SetTextI18n")
public void onClickDetect(View view)
{
String path = getResources().getResourceName(R.drawable.qrcode);
Mat img = Imgcodecs.imread(path + ".png");
Mat points = new Mat();
QRCodeDetector qrdetector = new QRCodeDetector();
detectStatus_text.setText("Detecting QRCode, standby...");
String data;
if (img.empty())
{
detectStatus_text.setText("Error could not load image file!");
return;
}
if (!qrdetector.detect(img, points))
{
detectStatus_text.setText("Error detecting QRCode!");
return;
}
data = qrdetector.decode(img, points);
if (data.isEmpty())
{
detectStatus_text.setText("Error decoding QRCode!");
return;
}
detectedData_text.append(path +"\n\n");
detectStatus_text.setText("QRCode successfully detected!");
}
}
It appears that Imgcodecs.imread() not finding the file path to load the file, if so I don't know how to get file correct path in app resources.
Note: I put qrcode.png file in app\src\main\res\drawable\qrcode.png.

I am not sure how to do with Imgcodecs.imread() in a proper way. However, if you only want to read a Mat object from a drawable resources, I have two workarounds
1) By using bitmap
Bitmap bMap=BitmapFactory.decodeResource(getResources(),R.drawable.qrcode);
Mat img = new Mat();
Utils.bitmapToMat(bMap, img);
where qrcode is a image under Resources folder of your Android
project. Then convert Bitmap to bytes or Mat and process in C++
(OpenCV) or Java with matToBitmap or MatToBitmap methods in
android-opencv. Ref and Ref2
2) Resource loader from org.opencv.android.utils
Mat img = null;
try {
img = Utils.loadResource(this, R.drawable.qrcode, CvType.CV_8UC4);
} catch (IOException e) {
e.printStackTrace();
}

Related

How can I import a lib file? scanner occur FileNotFoundException

I am getting the following error:
scan = new Scanner(new File("file:///android_lib/"+StationNM+".csv"));
I have 아현.csv in the lib folder, but android throws FileNotFoundException.
how can I solve this? adfasdfa
my source is
mport java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Scanner;
import java.lang.Object;
public class model {
public float modelPredict(String StationNM, String UPandDOWN, int day, int hour, int minute)
{
Scanner scan = null;
try {
scan = new Scanner(new File("file:///android_lib/"+StationNM+".csv"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ArrayList<String[]> records = new ArrayList<String[]>();
ArrayList<Integer> model_list = new ArrayList<Integer>();
while (scan.hasNext()) {
String[] record;
record = scan.nextLine().split(",");
records.add(record);
}
}
this issue was solved
scan = new Scanner(new File("file:///android_lib/"+StationNM+".csv"));
The File constructor takes filesystem paths. What you are passing:
Is not a filesystem path, as paths do not have schemes like file:// or http:// or content://
Refers to a non-existent directory on the filesystem
I have 아현.csv in the lib folder
Put it in src/main/assets/ of your module. Pass in an AssetManager to your modelPredict() method, and use open() on AssetManager to get an InputStream that you can pass to the Scanner constructor. You get an AssetManager by calling getAssets() on a Context, such as your Activity or Service.

Glide, Clear cache when cache size is larger than 50 mb

I am using Glide library for image loading. There is lot of images in my app so I want to clear cache once cache size is larger than 50 mb.
Can someone help me to do so?
Call Glide.get(context).clearDiskCache() on outside the UI thread. (also consider clearMemory() too to prevent surprises after clearing disk cache) this worked for me
new Thread(new Runnable() {
#Override
public void run() {
Glide.get(MainActivity.this).clearDiskCache();
}
}).start();
There is lot of images in my app so I want to clear cache once cache size is larger than 50 mb.
in case you want to put limit 50 mb you can implement glide module
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.module.GlideModule;
import com.example.MyApplication;
import java.util.Locale;
public class LimitCacheSizeGlideModule implements GlideModule {
// Modern device should have 8GB (=7.45GiB) or more!
private static final int SMALL_INTERNAL_STORAGE_THRESHOLD_GIB = 6;
private static final int DISK_CACHE_SIZE_FOR_SMALL_INTERNAL_STORAGE_MIB = 50*1024*1024;
#Override
public void applyOptions(Context context, GlideBuilder builder) {
if (MyApplication.from(context).isTest()) return; // NOTE: StatFs will crash on robolectric.
double totalGiB = getTotalBytesOfInternalStorage() / 1024.0 / 1024.0 / 1024.0;
Log.i(String.format(Locale.US, "Internal Storage Size: %.1fGiB", totalGiB));
if (totalGiB < SMALL_INTERNAL_STORAGE_THRESHOLD_GIB) {
Log.i("Limiting image cache size to " + DISK_CACHE_SIZE_FOR_SMALL_INTERNAL_STORAGE_MIB + "MiB");
builder.setDiskCache(new InternalCacheDiskCacheFactory(context, DISK_CACHE_SIZE_FOR_SMALL_INTERNAL_STORAGE_MIB));
}
}
#Override
public void registerComponents(Context context, Glide glide) {
}
private long getTotalBytesOfInternalStorage() {
// http://stackoverflow.com/a/4595449/1474113
StatFs stat = new StatFs(Environment.getDataDirectory().getPath());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
return getTotalBytesOfInternalStorageWithStatFs(stat);
} else {
return getTotalBytesOfInternalStorageWithStatFsPreJBMR2(stat);
}
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private long getTotalBytesOfInternalStorageWithStatFs(StatFs stat) {
return stat.getTotalBytes();
}
#SuppressWarnings("deprecation")
private long getTotalBytesOfInternalStorageWithStatFsPreJBMR2(StatFs stat) {
return (long) stat.getBlockSize() * stat.getBlockCount();
}
}
and then in your manifest add it like this
<manifest
...
<application>
<meta-data
android:name="YourPackageNameHere.LimitCacheSizeGlideModule"
android:value="GlideModule" />
...
</application>
</manifest>

phonegap custom plugin for android advice needed

Hi I am in mobile app.
I have developed an app in phonegap (html5, JQuery, JS) and I want to develop a plugin to print to a BT printer.
I download printer manufacturer's SDK and I imported the appropriate .jar file to my project with the following way:
To include this library into your project:
Drag the appropriate library file into the Project Explorer from the SDK package
Right click the project folder and choose Properties
Click Java Build Path
Click Libraries and the Add JARs button
At the top of your main code add:
import com.starmicronics.stario.StarIOPort;
import com.starmicronics.stario.StarIOPortException;
import com.starmicronics.stario.StarPrinterStatus;
Now you can access all of StarIO’s methods!
I create the following plugin
js
var HelloPlugin = {
callNativeFunction: function (success, fail, resultType) {
return cordova.exec(success, fail, "com.tricedesigns.HelloPlugin", "nativeAction", [resultType]);
}
};
java
package com.tricedesigns;
import com.starmicronics.stario.StarIOPort;
import com.starmicronics.stario.StarIOPortException;
import com.starmicronics.stario.StarPrinterStatus;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.util.Log;
public class HelloPlugin extends Plugin {
public static final String NATIVE_ACTION_STRING="nativeAction";
public static final String SUCCESS_PARAMETER="success";
public static final String portName = "BT:";
public static final String portSettings = "mini";
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
Log.d("HelloPlugin", "Hello, this is a native function called from PhoneGap/Cordova!");
//only perform the action if it is the one that should be invoked
if (NATIVE_ACTION_STRING.equals(action)) {
String resultType = null;
try {
resultType = data.getString(0);
}
catch (Exception ex) {
Log.d("HelloPlugin", ex.toString());
}
byte[] texttoprint = resultType.toString().getBytes();
if (resultType.equals(SUCCESS_PARAMETER)) {
StarIOPort port = null;
return new PluginResult(PluginResult.Status.OK, "Yay, Success!!!");
}
else {
return new PluginResult(PluginResult.Status.ERROR, "Oops, Error :(");
}
}
return null;
}
}
which is working with no promblems.
When i try to include the below call to printer .jar method
port = StarIOPort.getPort(portName, portSettings, 10000, context);
I get Error: Status=2 Message=Class not found.
Where am i wrong????

bad base64 in android

Hi i am using the following code to parse a certificate details.Everything is fine except a bit problem mentioned below.
package android.net.http;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.security.cert.Certif`enter code here`icate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Base64InputStream;
import android.util.Log;
public class SslCertificate1Activity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
String text = "-----BEGIN CERTIFICATE-----\n"+
"MIIC/TCCAmagAwIBAgIBKjANBgkqhkiG9w0BAQQFADCBqDEiMCAGA1UEAxMZeG1sZ2F0ZXdheS5p\n"+
"dHMudXRleGFzLmVkdTEoMCYGA1UECxMfSW5mb3JtYXRpb24gVGVjaG5vbG9neSBTZXJ2aWNlczEq\n"+
"MCgGA1UEChMhVGhlIFVuaXZlcnNpdHkgb2YgVGV4YXMgYXQgQXVzdGluMQ8wDQYDVQQHEwZBdXN0\n"+
"aW4xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzAeFw0wNDA1MDkwNTMwMTBaFw0wNTA1MDQw\n"+
"NTMwMTBaMIGAMQswCQYDVQQGEwJVUzEOMAwGA1UECBMFVGV4YXMxDzANBgNVBAcTBkF1c3RpbjEq\n"+
"MCgGA1UEChMhVGhlIFVuaXZlcnNpdHkgb2YgVGV4YXMgYXQgQXVzdGluMRMwEQYDVQQLEwpUb29s\n"+
"cyBUZWFtMQ8wDQYDVQQDEwZDbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ6PABjb\n"+
"zXUkgo29S4uv1Qz9reo1/tP4pkQTGAldSbtA4hVtA/3sjw2+u3kgxYruAi2cXV2k0RPZhsUZjlDk\n"+
"jMPb/dlY81bD8gqe3lu3ezugJrlArlpfWN6PlufbTjxHSqIA0XD9R5/ZECaUV9dD43K5KdWUCy99\n"+
"YKDiSwVPO9F5AgMBAAGjXTBbMB0GA1UdDgQWBBRkCCpscEXxXu8Ba67p6zdh13ypjzAfBgNVHSME\n"+
"GDAWgBR2RsZH2kSY782kBROo92FAWS6sADAJBgNVHRMEAjAAMA4GA1UdDwQHAwUBEiRIkDANBgkq\n"+
"hkiG9w0BAQQFAAOBgQCtV1NzpdVBs5vyb8yLXNA3hA1LsmE/2QanXG4T3UN93BI4HQzx0idnkN1Y\n"+
"0RAQ1rjGeQ1pk3l2DWsPi9mTkCGmYs/EMLkKOBee9ad3BIG6sKwXgbgLyNLgda+Y1bo+SIomq/a7\n"+
"yP92UHMFEegfS/ssECA+Q3hHuU6in3AqLfWH1w==\n"+
"-----END CERTIFICATE-----";
int startIndex = 0;
String cert = text.substring(startIndex,text.length());
byte[] certBytes = cert.getBytes();
InputStream in = new Base64InputStream(new ByteArrayInputStream(
certBytes), 0);
CertificateFactory certFact = CertificateFactory.getInstance ("X.509");
Certificate certGen = certFact.generateCertificate(in);
X509Certificate x509 = (X509Certificate) certGen;
Log.i("","certificate details:"+x509);
}
catch (Exception e)
{
Log.e("testapp", "exception: " + e.getMessage());
}
}
}
and I am getting android.util.BASE64DataException:bad base-64 at the foloowing line when I launced debugger:-
Certificate certGen = certFact.generateCertificate(in);
Seems like there is something wrong with Base64InputStream.Please help in rectifying the Exception.
Thanks in advance
No, nothing is wrong with Base64InputStream. When in doubt, you should suspect your own code of being incorrect rather than everyone else's.
What's wrong is that you're giving Base64InputStream data that ends with "-----END CERTIFICATE-----" after the padding part.
You should only be passing in the bit between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----".
It looks like you've started thinking about that already here:
int startIndex = 0;
String cert = text.substring(startIndex,text.length());
... but that code isn't going to do anything - when startIndex is 0, substring is going to return the whole string...
Personally I'd consider doing the Base64 conversion first using the Base64 class to convert the base64 part of the string (you still need to get the substring) to a byte[] and then create a ByteArrayInputStream around that.

how to display a html page with image in android?

hi i want to display my html image on android emulator, please help
package com.Htmlview;
import ja va.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.webkit.WebView;
public class Htmlview extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
WebView webview = new WebView(this);
setContentView(webview);
try {
String imageString="<html><body>" +
"<h2>Norwegian Mountain Trip</h2>" +
"<img src=\"C:/Users/Public/Pictures/Sample Pictures/pulpit.jpg\" alt=\"Pulpit rock\" width=\"304\" height=\"228\" /></body></html>";
AssetManager mgr = this.getAssets();
InputStream is = mgr.open("index3.html");
BufferedInputStream in = new BufferedInputStream(is); // read the contents of the file
webview.loadData(MessageFormat.format(imageString,arguments),"text/html", "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
}
}
You're never going to be able to access something on your workstation's hard drive from within Android. What you want to do is put the image into the assets folder in your Android app (which will then get bundled into the app) and link to it appropriately with file:///android_assets/. There are other ways of dealing with the issue, but that is the simplest.

Categories

Resources