This is an Android app to convert an RGB image to grayscale and display it on a screen. According to logcat, I am getting an unsatisfiedLinkError from
Mat ImageMat = new Mat (image.getHeight(), image.getWidth(), CvType.CV_8U, new Scalar(4));
What is wrong?
public class ImwriteActivity extends Activity /*implements OnClickListener*/{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imwrite);
ImageView img = (ImageView) findViewById(R.id.imageView1);
//get image from sdcard
File f = new File(Environment.getExternalStorageDirectory().getPath()+"/Test.jpg");
Bitmap image = BitmapFactory.decodeFile(f.getAbsolutePath());
//convert Bitmap to Mat
Mat ImageMat = new Mat (image.getHeight(), image.getWidth(), CvType.CV_8U, new Scalar(4));
Bitmap myBitmap32 = image.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(myBitmap32, ImageMat);
//change the color
Imgproc.cvtColor(ImageMat, ImageMat, Imgproc.COLOR_RGB2GRAY,4);
//convert the processed Mat to Bitmap
Bitmap resultBitmap = Bitmap.createBitmap(ImageMat.cols(), ImageMat.rows(),Bitmap.Config.ARGB_8888);;
Utils.matToBitmap(ImageMat, resultBitmap);
//Set member to the Result Bitmap. This member is displayed in an ImageView
img.setImageBitmap(resultBitmap);
}
}
onCreate is the wrong place to put your opencv code, since it depends on native, c++ code.
first you need to load the opencv so's:
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
if (status == LoaderCallbackInterface.SUCCESS ) {
// now we can call opencv code !
} else {
super.onManagerConnected(status);
}
}
};
#Override
public void onResume() {;
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5,this, mLoaderCallback);
// you may be tempted, to do something here, but it's *async*, and may take some time,
// so any opencv call here will lead to unresolved native errors.
}
#Override
public void onCameraViewStarted(int width, int height) {
// probably the best place for your opencv code
}
Related
I am creating an app that pulls images from urls and puts them into a recyclerview. The user can then access those images and view it fullscreen. This is achieved with Picasso. I would now like the ability to fingerpaint over the image loaded with Picasso with an onTouchEvent or something but not sure how to do it.
This class sets the image to a map_edit_gallery.xml loaded with Picasso:
public class EditMapImage extends AppCompatActivity {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_edit_gallery);
checkIntent();
//Find savebutton
ImageButton saveMapButton = findViewById(R.id.saveEditImagebutton);
saveMapButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),"Saved",Toast.LENGTH_SHORT).show();
}
});
}
//This will check to see if the intent extras exist and if they do get the extra
private void checkIntent(){
if(getIntent().hasExtra("image_url") && getIntent().hasExtra("name_url")){
String imageUrl = getIntent().getStringExtra("image_url");
String nameUrl = getIntent().getStringExtra("name_url");
setMapImage(imageUrl, nameUrl);
}
}
private void setMapImage(String imageUrl, String nameUrl){
//Set the Text view
TextView name = findViewById(R.id.mapNameEditor);
name.setText(nameUrl);
//Set the Image
ImageView imageView = findViewById(R.id.mapEditScreen);
Picasso.get().load(imageUrl).into(imageView);
Picasso picasso = Picasso.get();
DrawToImage myTransformation = new DrawToImage();
picasso.load(imageUrl).transform(myTransformation).into(imageView);
}
}
EDIT:
This class has allowed me to draw over the loaded image using canvas but cannot figure out how to use touch to draw:
public class DrawToImage implements Transformation {
#Override
public String key() {
// TODO Auto-generated method stub
return "drawline";
}
public Bitmap transform(Bitmap bitmap) {
// TODO Auto-generated method stub
synchronized (DrawToImage.class) {
if(bitmap == null) {
return null;
}
Bitmap resultBitmap = bitmap.copy(bitmap.getConfig(), true);
Canvas canvas = new Canvas(resultBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
canvas.drawLine(0, resultBitmap.getHeight()/2, resultBitmap.getWidth(), resultBitmap.getHeight()/2, paint);
bitmap.recycle();
return resultBitmap;
}
}
}
Try using the image selected by the user to set it in a canvas object and draw on the canvas object itself, as opposed to the image. There are plenty of tutorials out there to help you with how to draw on a canvas.
This process isn't connected with the Picasso Image Library in any way so I would recommend first getting the image through Picasso, then sending the image into your custom canvas implementation, then returning a bitmap/drawable which you could set into Picasso after editing.
There's also plenty of tutorials on how to export an image from the canvas to get your edited image when you need it.
I hope this helped, Panos.
I am trying to check whether an ImageView was loaded with an image, and that the URL actually had an image resource.
ImageView dynamicImageView = new ImageView(context)
Picasso.get()
.load(myURL)
.resize(myWidth, myWidth)
.centerCrop()
.into(dynamicImageView, new Callback() {
#Override
public void onSuccess() {
Drawable drawable = dynamicImageView.getDrawable();
boolean hasImage = (drawable != null);
if (hasImage && (drawable instanceof BitmapDrawable)) {
hasImage = ((BitmapDrawable)drawable).getBitmap() != null;
}
}
#Override
public void onError(Exception e) {
}
});
This always returns true since Picasso automatically fills the default drawable placeholder into the dynamicImageView.
How should I go about it so that I always get a "truthful" result where the URL had no image resource?
Thank you all in advance.
You can go with Target callback:
private Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
}
#Override
public void onBitmapFailed() {
}
}
And while loading image, you need to write:
Picasso.with(this).load(myURL).into(target);
Just for the information:
onBitmapLoaded() mostly used to perform image operations before we load into the view actually.
Picasso.LoadedFrom describes where the image was loaded from, whether it's MEMORY, DISK or NETWORK.
I would like to use Glide to load bitmap to ImageView after cropping and re-sizing a bitmap.
I don't want to use ImageView.setImageBitmap(bitmap); because I am loading lots of images and it might be taking up some memory, although the images are small in size, I just need to use Glide because I know it optimises image caching.
I read this post, but I didn't quite understand his solution when I tried implementing it. So maybe someone has a cleaner and more easily understandable solution.
This is my code which picks up an image and creates a bitmap out of it.
I need to use glide instead of ImageView.setImageBitmap(bitmap);.
new AsyncTask<String, Void, Void>() {
Bitmap theBitmap = null;
Bitmap bm = null;
#Override
protected Void doInBackground(String... params) {
String TAG = "Error Message: ";
try {
//Load the image into bitmap
theBitmap = Glide.
with(mContext).
load("http://example.com/imageurl").
asBitmap().
into(-1, -1).
get();
//resizes the image to a smaller dimension out of the main image.
bm = Bitmap.createBitmap(theBitmap, 0, 0, 210, 80);
} catch (final ExecutionException e) {
Log.e(TAG, e.getMessage());
} catch (final InterruptedException e) {
Log.e(TAG, e.getMessage());
} catch (final NullPointerException e) {
//
}
return null;
}
#Override
protected void onPostExecute(Void dummy) {
if (null != theBitmap) {
//Set image to imageview.
**// I would like to Use Glide to set the image view here Instead of .setImageBitmap function**
holder.mImageView.setImageBitmap(bm);
holder.mImageView.setAdjustViewBounds(true);
holder.mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
}
}.execute();
You don't need AsyncTask to load image with Glide. Glide load image asynchronys.
Try to use this code:
Glide.with(mContext)
.load("http://example.com/imageurl")
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// you can do something with loaded bitmap here
// .....
holder.mImageView.setImageBitmap(resource);
}
});
I'm trying to do something like this:
Android Map api v2 Custom marker with ImageView
But I'm stuck on using image loader.
Trying:
Bitmap bmImg = imageLoader.loadImageSync(url);
LogCat gives me
04-13 14:11:44.953: E/ImageLoader(18542): android.os.NetworkOnMainThreadException
Here's is my code. I have an ArrayList camera with all information needed (titrle, position, url, etc).
public void drawPicsOnMap()
{
String title = null;
String place = null;
for (int i = 0; i<camera.size(); i++)
{
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(80, 80, conf);
Canvas canvas = new Canvas(bmp);
// paint defines the text color,
// stroke width, size
Paint color = new Paint();
color.setTextSize(35);
color.setColor(Color.BLACK);
Camera cam = camera.get(i);
LatLng coord = new LatLng(cam.lat, cam.lon);
title = Integer.toString(cam.id);
place = cam.place;
String url = cam.img;
Bitmap bmImg = imageLoader.loadImageSync(url);
//modify canvas
canvas.drawBitmap(bmImg, 0,0, color);
canvas.drawText(title, 30, 40, color);
Marker mark = map.addMarker(new MarkerOptions()
.position(coord)
.title(title)
.snippet(place)
.icon(BitmapDescriptorFactory
.fromBitmap(bmp)));
markers.put(mark.getId(), url);
}
}
Try this:
imageLoader.loadImage(url, new SimpleImageLoadingListener(){
#Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
//write your code here to use loadedImage
}
});
Here
onLoadingComplete will be called on UI thread which makes it thread safe
You can not do any networking on the main thread. See for description. UIL usually creates the thread and stuff for you when you call displayImage, but loadImageSync does not. Either create a thread and load it or use an AsynTask.
I am running a java script for canny edge detection, and when I use the keyword Mat anywhere in the program, or even the other Mat variables, the app is not loading.How can I resolve this.
The code I am using is the following.
public class MainActivity extends Activity {
Mat m;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MediaPlayer mpButtonClick = MediaPlayer.create(this, R.raw.button_click);
final String TAG = "OCVSample::Activity";
BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
m=new Mat();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
ImageView imageSource=null,imageAfter = null;
Bitmap source=null,result = null;
imageSource = (ImageView)findViewById(R.id.imageView1);
source=BitmapFactory.decodeResource(getResources(), R.drawable.strips1);
Mat matSource = null;
// Handle initialization error
Utils.bitmapToMat(source, matSource);
Mat matResult = null;
Imgproc.Canny(matSource, matResult, 80, 90);
Utils.matToBitmap(matResult,result);
imageAfter.setImageBitmap(result);
you can only use opencv code after BaseLoaderCallback finished ( and the dll's/so's were loaded ).
so, doing the Canny code in onCreate won't work ( it's too early for that ).
either move it after the LoaderCallbackInterface.SUCCESS: or to onCameraViewStarted() or similar
(btw, this only got obvious after applying some work on your horribly formatted code ... )