I am using the following code to play the gif, but here it keeps on repeating the gif play.
Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setAutoPlayAnimations(true)
. // other setters
.build();
mSimpleDraweeView.setController(controller);
How can i play it once?
Well, I have not used fresco for GIF file but might be this one could help you out. Use below library for GIF file loading.
Refer this link
This is my code, and it works well:
public class MainActivity extends AppCompatActivity {
private GifImageView mGigImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGigImageView = (GifImageView) findViewById(R.id.mgif);
GifDrawable gifDrawable = null;
try {
gifDrawable = new GifDrawable(getResources(), R.drawable.ani_1);
gifDrawable.setLoopCount(1);
} catch (IOException e) {
e.printStackTrace();
}
mGigImageView.setImageDrawable(gifDrawable);
}
}
You can use the Glide for GIF..It is better library.
Glide is quite similar to Picasso but this is much faster than Picasso.
Glide consumes less memory than Picasso.
What that Glide has but Picasso doesn't
An ability to load GIF Animation to a simple ImageView might be the most interesting feature of Glide. And yes, you can't do that with Picasso.
Some important links-
1. https://github.com/bumptech/glide
2. http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
You can also use the Ion library to load the gif. Refer this link click here
Gradle dependencies for it:-
dependencies {
...
compile 'com.android.support:support-v4:23.1.0'
compile 'com.koushikdutta.ion:ion:2.+'
}
To load the gif from the drawable like below:-
ImageView imgView=(ImageView) view.findViewById(R.id.imageView);
Ion.with(imgView)
.error(R.drawable.error_image)
.animateGif(AnimateGifMode.ANIMATE)
.load("android.resource://" + PackageName + "/" + R.drawable.loadingbh)
.withBitmapInfo();
And load the Image from the URL like :-
Ion.with(imgView)
.error(R.drawable.error_image)
.animateGif(AnimateGifMode.ANIMATE)
.load("https://www.beginnersheap.com/wp-content/uploads/2016/08/loading-BH.gif") ///LOAD YOUR URL GIF
.withBitmapInfo();
package com.splash;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.exp.R;
public class SplashViewAnimation extends View {
private Movie mMovie;
private long mMovieStart;
public SplashViewAnimation(Context context) {
super(context);
setFocusable(true);
java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.coca_cola2); // Put your gif file here..
mMovie = Movie.decodeStream(is);
}
public SplashViewAnimation(Context context, AttributeSet attrSet) {
super(context, attrSet);
setFocusable(true);
java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.coca_cola2);
mMovie = Movie.decodeStream(is);
}
public SplashViewAnimation(Context context, AttributeSet attrSet, int defStyle) {
super(context, attrSet, defStyle);
setFocusable(true);
java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.coca_cola2);
mMovie = Movie.decodeStream(is);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0x00000000);
Paint p = new Paint();
p.setAntiAlias(true);
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if(mMovie != null){
int dur = mMovie.duration();
if (dur == 0)
{
dur = 1000;
}
int relTime = (int) ((now - mMovieStart) % dur);
mMovie.setTime(relTime);
mMovie.draw(canvas,(int)((getWidth() - mMovie.width()) - getWidth()*.80),
(int)((getHeight() - (mMovie.height()-6)) - getHeight()*.10));
invalidate();
}
}
}
/// Use above code in main class :-
SplashViewAnimation sp = new SplashViewAnimation(this);
FrameLayout mainLayout = (FrameLayout)findViewById(R.id.main_layout_id);
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
layoutParams.gravity= Gravity.BOTTOM | Gravity.LEFT;
mainLayout.addView(sp,layoutParams);
I know this is a very late reply. However, I couldn't find a correct answer after searching for over a couple of hours(I wanted to use only fresco and avoid adding another library for just one GIF). This could help someone like me searching for the answer. I could finally achieve it with the following workaround.
ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
#Override
public void onFinalImageSet(
String id,
#Nullable ImageInfo imageInfo,
#Nullable final Animatable anim) {
if (anim != null) {
try {
//This is important to handle the loop. We are getting the field from class and //setting the loop count
Field field = AbstractAnimatedDrawable.class.getDeclaredField("mLoopCount");
field.setAccessible(true);
field.set(anim, 1);
} catch (Exception e) {
e.printStackTrace();
}
anim.start();
}
}
};
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri).setAutoPlayAnimations(false).setControllerListener(controllerListener)
// other setters
.build();
simpleImageView.setController(controller);
Hope this helps.
Thank you.
Related
I want to create animated splash screen using gif image. I have used Glide library because it supports gif images.
I have done following things to achieve this:
Created splash.xml with an imageview in it.
<ImageView
android:id="#+id/iv_gif_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Inside SplashActivity.java
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
ImageView ivImage = (ImageView) findViewById(R.id.iv_gif_view);
Glide.with(this).load(R.drawable.splash_xxhdpi_2)
.asGif().into(ivImage);
}
But when I run the application screen goes black nothing appears on the screen. I'm using Glide compile 'com.github.bumptech.glide:glide:3.6.1'
You can try this way
public class GifImageView extends View {
private InputStream mInputStream;
private Movie mMovie;
private int mWidth, mHeight;
private long mStart;
private Context mContext;
public GifImageView(Context context) {
super(context);
this.mContext = context;
}
public GifImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GifImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
if (attrs.getAttributeName(1).equals("background")) {
int id = Integer.parseInt(attrs.getAttributeValue(1).substring(1));
setGifImageResource(id);
}
}
private void init() {
setFocusable(true);
mMovie = Movie.decodeStream(mInputStream);
mWidth = mMovie.width();
mHeight = mMovie.height();
requestLayout();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mWidth, mHeight);
}
#Override
protected void onDraw(Canvas canvas) {
long now = SystemClock.uptimeMillis();
if (mStart == 0) {
mStart = now;
}
if (mMovie != null) {
int duration = mMovie.duration();
if (duration == 0) {
duration = 1000;
}
int relTime = (int) ((now - mStart) % duration);
mMovie.setTime(relTime);
mMovie.draw(canvas, 0, 0);
invalidate();
}
}
public void setGifImageResource(int id) {
mInputStream = mContext.getResources().openRawResource(id);
init();
}
public void setGifImageUri(Uri uri) {
try {
mInputStream = mContext.getContentResolver().openInputStream(uri);
init();
} catch (FileNotFoundException e) {
Log.e("GIfImageView", "File not found");
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GifImageView gifImageView = (GifImageView) findViewById(R.id.GifImageView);
gifImageView.setGifImageResource(R.drawable.android);
}
}
http://www.mavengang.com/2016/05/02/gif-animation-android/
http://www.geeks.gallery/how-to-display-the-animated-gif-image-in-android/
Android does not support GIF so avoid using it since it is memory consuming. Glide is nice image caching library and luckily it supports gif images.
I'm sharing alternate and efficient way to achieve animated splash screen.
Create splash.xml as usual with an image view.
Take out each frame from your gif image. I have used splash_hdpi_1, splash_hdpi_2, splash_hdpi_3 for example.
create splash_gif_animation.xml in drawable with below code
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="#drawable/splash_hdpi_1"
android:duration="150"/>
<item
android:drawable="#drawable/splash_hdpi_2"
android:duration="150"/>
<item
android:drawable="#drawable/splash_hdpi_3"
android:duration="150"/>
</animation-list>
In your SplashActivity.java put below code
ImageView ivImage = (ImageView) findViewById(R.id.your_image_view);
ivImage.setBackgroundResource(R.drawable.splash_gif_animation);
AnimationDrawable splashAnimation = (AnimationDrawable) ivImage.getBackground();
splashAnimation.start();
You are done:)
Try this:
ImageView ivImage= (ImageView) findViewById(R.id.iv_gif_view);
GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(ivImage);
Glide.with(this)
.load(R.drawable.splash_xxhdpi_2)
.into(imageViewTarget);
Hello stackoverflow I'm trying to develop an android application to play my own GIF, here is the code snippet
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
AnimationView.java
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;
public class AnimationView extends View {
private Movie mMovie;
private long mMovieStart;
private static final boolean DECODE_STREAM = true;
private int mDrawLeftPos;
private int mHeight, mWidth;
private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int len;
try {
while ((len = is.read(buffer)) >= 0) {
os.write(buffer, 0, len);
}
} catch (java.io.IOException e) {
}
return os.toByteArray();
}
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.scanning);
if (DECODE_STREAM) {
mMovie = Movie.decodeStream(is);
} else {
byte[] array = streamToBytes(is);
mMovie = Movie.decodeByteArray(array, 0, array.length);
}
}
#Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
{
int p_top = this.getPaddingTop(), p_bottom = this.getPaddingBottom();
mWidth = mMovie.width();
mHeight = mMovie.height();
// Calculate new desired height
final int desiredHSpec = MeasureSpec.makeMeasureSpec( mHeight + p_top + p_bottom , MeasureSpec.EXACTLY );
setMeasuredDimension( widthMeasureSpec, desiredHSpec );
super.onMeasure( widthMeasureSpec, desiredHSpec );
// Update the draw left position
mDrawLeftPos = Math.max( ( this.getWidth() - mWidth ) / 2, 0) ;
}
#Override
public void onDraw(Canvas canvas) {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (mMovie != null) {
int dur = mMovie.duration();
if (dur == 0) {
dur = 3000;
}
int relTime = (int) ((now - mMovieStart) % dur);
// Log.d("", "real time :: " +relTime);
mMovie.setTime(relTime);
mMovie.draw(canvas, mDrawLeftPos, this.getPaddingTop());
invalidate();
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<com.example.androidgifwork.AnimationView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</LinearLayout>
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidgifwork"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="com.example.androidgifwork.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
When I run the above code snippet GIF is not at all running, but when I remove android:targetSdkVersion="19" GIF running, please help me to solve this riddle.
Thanks
2017 UPDATED ANSWER
To play GIF in android use Glide library to load any image or GIF.
Glide.with(context)
.load(YOUR_GIF)
.into(YOUR_IMAGE_VIEW);
Use Glide to load normal images, images from server or even to load GIF as well. Also have a look at Picasso android image loading library which is similar to Glide but as of now(16 Apr 2017) Picasso doesn't support GIF loading in android yet.
######################################################################
OLD ANSWER
For all Those who want to play GIF in your app please find the code below
PlayGifView.java
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
public class PlayGifView extends View{
private static final int DEFAULT_MOVIEW_DURATION = 1000;
private int mMovieResourceId;
private Movie mMovie;
private long mMovieStart = 0;
private int mCurrentAnimationTime = 0;
#SuppressLint("NewApi")
public PlayGifView(Context context, AttributeSet attrs) {
super(context, attrs);
/**
* Starting from HONEYCOMB have to turn off HardWare acceleration to draw
* Movie on Canvas.
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
public void setImageResource(int mvId){
this.mMovieResourceId = mvId;
mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
requestLayout();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(mMovie != null){
setMeasuredDimension(mMovie.width(), mMovie.height());
}else{
setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
}
}
#Override
protected void onDraw(Canvas canvas) {
if (mMovie != null){
updateAnimtionTime();
drawGif(canvas);
invalidate();
}else{
drawGif(canvas);
}
}
private void updateAnimtionTime() {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) {
mMovieStart = now;
}
int dur = mMovie.duration();
if (dur == 0) {
dur = DEFAULT_MOVIEW_DURATION;
}
mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
}
private void drawGif(Canvas canvas) {
mMovie.setTime(mCurrentAnimationTime);
mMovie.draw(canvas, 0, 0);
canvas.restore();
}
}
In your activity class use the following code to play GIF
PlayGifView pGif = (PlayGifView) findViewById(R.id.viewGif);
pGif.setImageResource(<Your GIF file name Eg: R.drawable.infinity_gif>);
XML layout
<yourPacckageName.PlayGifView
android:id="#+id/viewGif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
Use Glide to load any gif from your project's raw folder or external URL into ImageView, ImageButtons or similar [Glide targets][2]
Glide.with(getActivity()).load(R.raw.alarm).asGif().into(btnAlert);
If you can use a WebView, GIFs will play directly over it. But I am not sure, in your case whether you want to put it in a Webview or not.
add this to your dependencies (build.gradle)
allprojects {
repositories {
mavenCentral()
}
}
dependencies {
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
}
and use this in xml to show your gif
<pl.droidsonroids.gif.GifTextView
android:id="#+id/gifTextView2"
android:layout_width="230dp"
android:layout_height="200dp"
android:layout_weight="1"
android:src="#drawable/dev_option_gif"
/>
More info at: https://github.com/koral--/android-gif-drawable
Android provides the class android.graphics.Movie. This class is capable of decoding and playing InputStreams. So for this approach, we create a class GifMovieView and let it inherit from View a detailed tutorial is given at http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-in-android-part-1/
Source Code
https://drive.google.com/open?id=0BzBKpZ4nzNzUZy1BVlZSbExvYUU
** android:hardwareAccelerated="false" in Manifest File**
package com.keshav.gifimageexampleworking;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class MainActivity extends AppCompatActivity
{
private GifImageView gifImageView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gifImageView = (GifImageView) findViewById(R.id.GifImageView);
gifImageView.setGifImageResource(R.drawable.success1);
}
#Override
protected void onResume()
{
super.onResume();
//refresh long-time task in background thread
new Thread(new Runnable() {
#Override
public void run() {
try {
//dummy delay for 2 second
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//update ui on UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
gifImageView.setGifImageResource(R.drawable.success);
}
});
}
}).start();
}
}
package com.keshav.gifimageexampleworking;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.net.Uri;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class GifImageView extends View {
private InputStream mInputStream;
private Movie mMovie;
private int mWidth, mHeight;
private long mStart;
private Context mContext;
public GifImageView(Context context) {
super(context);
this.mContext = context;
}
public GifImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GifImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
if (attrs.getAttributeName(1).equals("background")) {
int id = Integer.parseInt(attrs.getAttributeValue(1).substring(1));
setGifImageResource(id);
}
}
private void init() {
setFocusable(true);
mMovie = Movie.decodeStream(mInputStream);
mWidth = mMovie.width();
mHeight = mMovie.height();
requestLayout();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mWidth, mHeight);
}
#Override
protected void onDraw(Canvas canvas) {
long now = SystemClock.uptimeMillis();
if (mStart == 0) {
mStart = now;
}
if (mMovie != null) {
int duration = mMovie.duration();
if (duration == 0) {
duration = 1000;
}
int relTime = (int) ((now - mStart) % duration);
mMovie.setTime(relTime);
mMovie.draw(canvas, 10, 10);
invalidate();
}
}
public void setGifImageResource(int id) {
mInputStream = mContext.getResources().openRawResource(id);
init();
}
public void setGifImageUri(Uri uri) {
try {
mInputStream = mContext.getContentResolver().openInputStream(uri);
init();
} catch (FileNotFoundException e) {
Log.e("GIfImageView", "File not found");
}
}
}
For devices running API 29(Pie) & above you can use AnimatedImageDrawable to play GIF(s) and WebP animated images.
Here's a sample:
ImageView imgGif = findViewById(R.id.imgGif);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
drawable = ImageDecoder.decodeDrawable(ImageDecoder.createSource(getResources(), R.drawable.giphy));
imgGif.setImageDrawable(drawable);
if (drawable instanceof AnimatedImageDrawable) {
((AnimatedImageDrawable) drawable).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Using this provides more control & features you can use on the image such as:
Checking whether the gif is running
Starting & stopping the playback.
Applying color filters
Changing image shape
and much more
You can also use Coil library, which gives you a bit less control over Gif images than Glide does. But still gives simple implementation if you just want to load the GIF once and show. Probably, if you want to repeat that you need to trigger the drawable again or just call the load function once again. Anyway even if calling load again the resources should be cached under the hood(something to be investigated, not 100% sure).
Everything you need is adding dependency:
implementation "io.coil-kt:coil-gif:1.0.0"
And specifying your decoding mechanism:
val imageLoader = ImageLoader.Builder(context)
.componentRegistry {
if (SDK_INT >= 28) {
add(ImageDecoderDecoder())
} else {
add(GifDecoder())
}
}
.build()
That's all go-ahead and load images/gifs directly in your image views:
app_logo.load("needed_gif_url")
Don't forget to pass the needed image loader to each request where you need your decoder to be used, as for GIFs. Or just make your custom imageLoader as default for each request:
Coil.setImageLoader(imageLoader)
Animated GIFs in Android is a difficult topic. It is an issue that has been discussed heavily and still, it is very difficult for developers to bring GIFs to life. using glide and pl.droidsonroids.gif:android-gif-drawable made some problem to build gradle. so I found a method that not using any dependencies.I used this method to load the gif in my views:
GifAnimView.java:
package com.app.samplegif;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.graphics.Paint;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;
import com.app.samplegif.R;
import java.io.IOException;
import java.io.InputStream;
#SuppressLint("NewApi")
public class GifAnimView extends View {
private Context _context;
private Movie gifMovie;
private String gifName = "not set";
private InputStream gifStream;
private int width;
private int height;
private long startTime;
private Paint paint;
public GifAnimView(Context context, AttributeSet attrs) {
super(context,attrs);
initGif(context,attrs);
_context = context;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (gifStream == null || gifMovie == null) {
canvas.drawColor(Color.WHITE);
canvas.drawText(gifName,width/2, height /2,paint);
return;
}
long now = SystemClock.uptimeMillis();
int relTime = (int) ((now - startTime) % gifMovie.duration());
gifMovie.setTime(relTime);
gifMovie.draw(canvas, 0, 0);
this.invalidate();
}
private void initGif(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.GifAnimView, 0, 0);
gifName = a.getString(R.styleable.GifAnimView_gifSrc);
try {
gifStream =context.getAssets().open(gifName);
gifMovie = Movie.decodeStream(gifStream);
startTime = SystemClock.uptimeMillis();
} catch (IOException e) {
e.printStackTrace();
}
paint = new Paint();
paint.setTextSize(40);
paint.setTextAlign(Paint.Align.CENTER);
paint.setStyle(Paint.Style.FILL);
a.recycle();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
this.width = w;
this.height = h;
super.onSizeChanged(w, h, oldw, oldh);
}
}
create attrs.xml in res/values folder:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="GifAnimView">
<attr name="gifSrc" format="string" localization="suggested" />
</declare-styleable>
</resources>
copy your.gif file into src/main/assets/ folder
activity_main.xml:
you can use app:gifSrc attribute as name of your gif that exist in assets folder.
// ....
<com.app.samplegif.GifAnimView
android:id="#+id/gif_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginLeft="30dp"
android:layout_marginTop="20dp"
app:gifSrc="your.gif" />
// ....
I'm developing an App which draws lines over a bunch of Images. To choose these images, I have a radio group and, whenever the user clicks in a radio button, the image is load with all its own drawings.
In my radio listenner I have the following code:
bitmap = BitmapUtils.decodeSampledBitmapFromResource(root + DefinesAndroid.CAMINHO_SHOPPINGS_SDCARD + nomeImagemAtual, size.x, size.y);
mImage.setImageBitmap(bitmap);
mImage.setDrawLines(true);
mImage.setImageBitmap(loadBitmapFromView(mImage));
the decodeSampledBitmapFromResource method I got from this link on android developers (it loads bitmaps more effitiently) http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
And here's the method I call to get a Bitmap of a View
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
I'm setting the image Bitmap of mImage because I'm using ImageViewTouch library (which enables pinch zooming over an ImageView) and if I don't do it, all the canvas drawing is deleted with any interaction over the image (like zooming in/out).
The error log is the following
07-11 21:13:41.567: E/AndroidRuntime(20056): java.lang.IllegalArgumentException: width and height must be > 0
07-11 21:13:41.567: E/AndroidRuntime(20056): at android.graphics.Bitmap.createBitmap(Bitmap.java:638)
07-11 21:13:41.567: E/AndroidRuntime(20056): at android.graphics.Bitmap.createBitmap(Bitmap.java:620)
I'm almost sure that this error is occuring cause the image bitmap is not completely loaded when I call getBitmapFromView method.
How can I know when the view is loaded completely?
Call loadBitmapFromView in a such way:
mImage.post(new Runnable() {
#Override
public void run() {
loadBitmapFromView(mImage);
}
});
Runnable provided to post() method will be executed after view measuring and layouting, so getWidth() and getHeight() will return actual width and height.
What else can you do, is measuring View manually, by invoking measure, and then taking result from getMeasuredWidth() and getMeasuredHeight(). But I do not recommend this way.
There is actually another, more reliable way to do that by using ViewTreeObserver.OnPreDrawListener. And here is an example:
mImage.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
try {
loadBitmapFromView(mImage);
// Note that returning "true" is important,
// since you don't want the drawing pass to be canceled
return true;
} finally {
// Remove listener as further notifications are not needed
mImage.getViewTreeObserver().removeOnPreDrawListener(this);
}
}
});
Using OnPreDrawListener guarantees that View was measured and layouted, while View#post(Runnable) just executes your Runnable when all Views are already most likely measured and layouted.
Below is a working NotifyImageView class that incorporates Dmitry's method above
and adds code to notify only after the ImageView is truly usable.
I hope you find it useful.
`
public interface NotifyImageHolder {
public void notifyImageChanged(final NotifyImageView thePosterImage, final int width, final int height);
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
public class NotifyImageView extends ImageView {
private boolean mImageChanged;
private NotifyImageHolder mHolder;
private boolean mImageFinished;
public NotifyImageView(Context context) {
super(context);
init();
}
public NotifyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public NotifyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
protected void init() {
mImageChanged = false;
mImageFinished = false;
mHolder = null;
monitorPreDraw();
}
// so we can tell when the image finishes loading..
protected void monitorPreDraw() {
final NotifyImageView thePosterImage = this;
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
try {
return true; //note, that "true" is important, since you don't want drawing pass to be canceled
} finally {
getViewTreeObserver().removeOnPreDrawListener(this); // we don't need any further notifications
thePosterImage.buildDrawingCache();
mImageFinished = true;
}
}
});
}
public void setNotifyImageHolder(NotifyImageHolder holder) {
this.mHolder = holder;
}
public boolean isImageChanged() {
return mImageChanged;
}
public boolean isImageFinished() {
return mImageFinished;
}
public void notifyOff() {
mHolder = null;
}
// the change notify happens here..
#Override
public void setImageDrawable(Drawable noPosterImage) {
super.setImageDrawable(noPosterImage);
if (mHolder != null && mImageFinished) {
mImageFinished = false; // we send a single change-notification only
final NotifyImageView theNotifyImageView = this;
theNotifyImageView.post(new Runnable() {
#Override
public void run() {
if (mHolder != null) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
mImageChanged = true;
mHolder.notifyImageChanged(theNotifyImageView, width, height);
}
}
});
}
}
}
`
any idea how to play a fade in animation when image loads? Now it just blinks into place. I am using NetworkImageView from the Volley toolkit.
Also, is there a way to set loading and error bitmaps on the network image view without using the ImageLoader.get( .. ) ?
Thanks!
//EDIT: Okay, thanks to you all, but if we want to be perfectionists, we should only animate if loading from disk cache, overriding setImageBitmap would case animation to go off even if pulled from memcache
what you want to do is add a boolean shouldAnimate to ImageListener.onResponse like this
public static ImageListener getImageListener(final ImageView view, final int defaultImageResId,
final int errorImageResId) {
return new ImageListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (errorImageResId != 0) {
view.setImageResource(errorImageResId);
}
}
#Override
public void onResponse(ImageContainer response, boolean isImmediate, boolean shouldAnimate) {
if (response.getBitmap() != null) {
if (shouldAnimate) {
// ADDED
view.setAlpha(0f);
view.setImageBitmap(response.getBitmap());
view.animate().alpha(1f).setDuration(1000);
// END ADDED
} else {
view.setImageBitmap(response.getBitmap());
}
} else if (defaultImageResId != 0) {
view.setImageResource(defaultImageResId);
}
}
};
}
this is a method that sets the bitmap, no matter where it is from, so you need to set it to false to every usage in ImageLoader except for
class BatchedImageRequest {
private void batchResponse(String cacheKey, BatchedImageRequest request,
final VolleyError error) {
...
container.mListener.onResponse(container, false, true);
...
}
}
I've created a Gist for Copy & Paste usage - https://gist.github.com/ursusursus/5732521
Example implementation of CommonsWare's answer can be found here: https://gist.github.com/benvd/5683818.
Using a TransitionDrawable does add an extra layer of overdraw. If you want to avoid that, perhaps using a ViewPropertyAnimator might help.
The gist of it is basically to have the following snippet in your setImageBitmap():
TransitionDrawable td = new TransitionDrawable(new Drawable[]{
new ColorDrawable(android.R.color.transparent),
new BitmapDrawable(getContext().getResources(), bm)
});
setImageDrawable(td);
td.startTransition(FADE_IN_TIME_MS);
any idea how to play a fade in animation when image loads? Now it just blinks into place. I am using NetworkImageView from the Volley toolkit.
Off the cuff, create your own subclass of NetworkImageView and override setImageBitmap() to set up the alpha animation when the image is applied.
Also, is there a way to set loading and error bitmaps on the network image view without using the ImageLoader.get( .. ) ?
Call setImageBitmap() or setImageResource(), the same way you would with a regular ImageView.
This is my implementation of an animating NetworkImageView. It uses ObjectAnimator to fade in newly downloaded images, while cached images appear immediately. The implementation is pretty simple - only requiring you to override two NetworkImageView methods (setImageBitmap(Bitmap) and setImageUrl(String, ImageLoader). It uses the supplied ImageLoader to determine if the image is from cache.
public class AnimatedNetworkImageView extends NetworkImageView {
private static final int ANIM_DURATION = 500;
private boolean shouldAnimate = false;
public AnimatedNetworkImageView(Context context) {
super(context);
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
if(shouldAnimate) {
ObjectAnimator.ofFloat(this, "alpha", 0, 1).setDuration(ANIM_DURATION).start();
}
}
#Override
public void setImageUrl(String url, ImageLoader imageLoader) {
shouldAnimate = !imageLoader.isCached(url, 0, 0);
super.setImageUrl(url, imageLoader);
}
}
Hope this helps someone!
Also, is there a way to set loading and error bitmaps on the network
image view without using the ImageLoader.get( .. ) ?
NetworkImageView has methods for these two operations :
mNetworkImageView.setErrorImageResId(R.drawable.errorImageResourceId);
mNetworkImageView.setDefaultImageResId(R.drawable.loadingImageResourceId);
i recommend to use Picasso lib for loading images or Glide.
for loading images + animation use Picasso with this lib: com.github.florent37:materialimageloading
solution like this..
Picasso.with(this).load(bannerUrl).fit().centerCrop().into(bannerImage, new Callback() {
#Override
public void onSuccess() {
MaterialImageLoading.animate(bannerImage).setDuration(2000).start();
}
#Override
public void onError() {
}
});
if you maybe want some auth stuff for image loading use Glide like this..
GlideUrl glideUrl = new GlideUrl(bannerUrl, new LazyHeaders.Builder()
.addHeader("username", "heyyou")
.addHeader("password", "heyyou")
.build());
Glide.with(this).load(bannerUrl)
.centerCrop()
.crossFade(5000)
.into(bannerImage);
in addition Picasso for auth stuff have interceptor things but i used Glide.
maybe this helps..
This version of the NetworkImageView checks the ImageLoader upon url set if the image is in the cache and disables the animation. In contrast to #DalvikDroid answer this also respects the with/height/scalingType parameter for the cache.
/**
* NetworkImageView that fades-in the drawable upon complete download
*/
public class AnimatedNetworkImageView extends NetworkImageView {
private static final int ANIM_DURATION = 500;
private boolean shouldAnimate = true;
public AnimatedNetworkImageView(Context context) {
super(context);
init();
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
shouldAnimate = true; // animate by default. Only when {#link #determineIfAnimationIsNecessary} is called animation is dependent upon cache status
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
if (shouldAnimate) {
// your animation. Here with ObjectAnimator for example
ObjectAnimator.ofFloat(this, "alpha", 0, 1).setDuration(ANIM_DURATION).start();
}
}
#Override
public void setImageUrl(String url, ImageLoader imageLoader) {
shouldAnimate = determineIfAnimationIsNecessary(url, imageLoader);
super.setImageUrl(url, imageLoader);
}
/**
* checks if for the given imgUrl and imageLoader the view should animate when a bitmap is set.
* If this method is called before {#link NetworkImageView#setImageUrl(String, ImageLoader)} is called the view would not be animated if the image comes from the cache.
*
* #param imgUrl the image url
* #param imageLoader the image loader
*/
public boolean determineIfAnimationIsNecessary(String imgUrl, ImageLoader imageLoader) {
int width = getWidth();
int height = getHeight();
ScaleType scaleType = getScaleType();
boolean wrapWidth = false, wrapHeight = false;
if (getLayoutParams() != null) {
wrapWidth = getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT;
wrapHeight = getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT;
}
// Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
int maxWidth = wrapWidth ? 0 : width;
int maxHeight = wrapHeight ? 0 : height;
return !imageLoader.isCached(imgUrl, maxWidth, maxHeight, scaleType);
}
}
I am using:
Android 4.0.3
OpenCV 2.4.2
Samsung Galaxy S2
The face-detection example (from the opencv 2.4.2) is working perfectly.
But now, I would like to create a custom layout and actually work with just the data extracted from face detection and build a game on it. Not necessarily having the FdView surface taking the entire screen.
I have done these modifications below, but just a black screen is displayed. Nothing appears on the screen.
Added a fd.xml layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<org.opencv.samples.fd.FdView android:id="#+id/FdView"
android:layout_width="640dp"
android:layout_height="480dp"
android:visibility="visible"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:text="hi"/>
Modified the baseLoaderCallback of FdActivity.java:
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
// Load native libs after OpenCV initialization
System.loadLibrary("detection_based_tracker");
//EXPERIMENT
setContentView(R.layout.fd);
FdView surface = (FdView) (findViewById(R.id.FdView));
surface = mView;
// Create and set View
mView = new FdView(mAppContext);
mView.setDetectorType(mDetectorType);
mView.setMinFaceSize(0.2f);
//setContentView(mView);
// Check native OpenCV camera
if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!");
ad.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
ad.show();
}
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
Added constructors in FdView.java:
public FdView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public FdView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
Added constructors in SampleCvViewBase.java:
public SampleCvViewBase(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public SampleCvViewBase(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
I have precisely the same issue. Also trying to figure it out. I'm trying to display the image on a SurfaceView that doesn't take the whole screen. And with that I read that you can't have your Camera handler class and linked SurfaceView in different classes. So smashed everything into one.
So, at the moment I have the camera displaying on the SurfaceView, and copying the frame data to a mFrame variable. Basically just struggling to get the mFrame processed (in the multi-threading, Run(), function) and showing the result on the SurfaceView.
This is the code I have, if you think it would help: (excuse the formatting as my code is also a work in progress)
package org.opencv.samples.tutorial3;
import java.io.IOException;
import java.util.List;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.widget.TextView;
public class Sample3Native extends Activity implements SurfaceHolder.Callback,Runnable{
//Camera variables
private Camera cam;
private boolean previewing = false;
private SurfaceHolder mHolder;
private SurfaceView mViewer;
private int mFrameWidth;
private int mFrameHeight;
private byte[] mFrame;
private boolean mThreadRun;
private byte[] mBuffer;
Sample3View viewclass;
TextView text;
int value = 0;
//==========
int framecount = 0;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
// Load native library after(!) OpenCV initialization
System.loadLibrary("native_sample");
//constructor for viewclass that works on frames
viewclass = new Sample3View();
//setContentView(mView);
//OpenCam();
//setContentView(R.layout.main);
// Create and set View
CameraConstruct();
Camopen();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public Sample3Native()
{}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack);
}
//Camera construction
public void CameraConstruct()
{
mViewer = (SurfaceView)findViewById(R.id.camera_view);
text = (TextView)findViewById(R.id.text);
mHolder = mViewer.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
//calls camera screen setup when screen surface changes
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height)
{
CamStartDisplay();
}
public void Camclose()
{
if(cam != null && previewing)
{
cam.setPreviewCallback(null);
cam.stopPreview();
cam.release();
cam = null;
previewing = false;
}
mThreadRun = false;
viewclass.PreviewStopped();
}
//only open camera, and get frame data
public void Camopen()
{
if(!previewing){
cam = Camera.open();
//rotate display
cam.setDisplayOrientation(90);
if (cam != null)
{
//copy viewed frame
cam.setPreviewCallbackWithBuffer(new PreviewCallback()
{
public void onPreviewFrame(byte[] data, Camera camera)
{
synchronized (this)
{
System.arraycopy(data, 0, mFrame, 0, data.length);
this.notify();
}
//text.setText(Integer.toString(value++));
camera.addCallbackBuffer(mBuffer);
}
});
}
}//if not previewing
}
//start preview
public void CamStartDisplay()
{
synchronized (this)
{
if(cam != null)
{
//stop previewing till after settings is changed
if(previewing == true)
{
cam.stopPreview();
previewing = false;
}
Camera.Parameters p = cam.getParameters();
for(Camera.Size s : p.getSupportedPreviewSizes())
{
p.setPreviewSize(s.width, s.height);
mFrameWidth = s.width;
mFrameHeight = s.height;
break;
}
p.setPreviewSize(mFrameWidth, mFrameHeight);
List<String> FocusModes = p.getSupportedFocusModes();
if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
{
p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
cam.setParameters(p);
//set the width and height for processing
viewclass.setFrame(mFrameWidth, mFrameHeight);
int size = mFrameWidth*mFrameHeight;
size = size * ImageFormat.getBitsPerPixel(p.getPreviewFormat()) / 8;
mBuffer = new byte[size];
mFrame = new byte [size];
cam.addCallbackBuffer(mBuffer);
viewclass.PreviewStarted(mFrameWidth, mFrameHeight);
//start display streaming
try
{
//cam.setPreviewDisplay(null);
cam.setPreviewDisplay(mHolder);
cam.startPreview();
previewing = true;
}
catch (IOException e)
{
e.printStackTrace();
}
}//end of if cam != null
}//synchronising
}
//thread gets started when the screen surface is created
public void surfaceCreated(SurfaceHolder holder) {
//Camopen();
//CamStartDisplay();
(new Thread(this)).start();
}
//called when the screen surface is stopped
public void surfaceDestroyed(SurfaceHolder holder)
{
Camclose();
}
//this is function that is run by thread
public void run()
{
mThreadRun = true;
while (mThreadRun)
{
//text.setText(Integer.toString(value++));
Bitmap bmp = null;
synchronized (this)
{
try
{
this.wait();
bmp = viewclass.processFrame(mFrame);
}
catch (InterruptedException e) {}
}
if (bmp != null)
{
Canvas canvas = mHolder.lockCanvas();
if (canvas != null)
{
canvas.drawBitmap(bmp, (canvas.getWidth() - mFrameWidth) / 2, (canvas.getHeight() - mFrameHeight) / 2, null);
mHolder.unlockCanvasAndPost(canvas);
}
}//if bmp != null
}// while thread in run
}
}//end class
Sample3View as used in this class just includes the processFrame function as such:
package org.opencv.samples.tutorial3;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.TextView;
class Sample3View {
private int mFrameSize;
private Bitmap mBitmap;
private int[] mRGBA;
private int frameWidth;
private int frameHeight;
private int count = 0;
Sample3Native samp;
//constructor
public Sample3View()
{
}
public void setFrame(int width,int height)
{
frameWidth = width;
frameHeight = height;
}
public void PreviewStarted(int previewWidtd, int previewHeight) {
mFrameSize = previewWidtd * previewHeight;
mRGBA = new int[mFrameSize];
mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888);
}
public void PreviewStopped() {
if(mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
mRGBA = null;
}
public Bitmap processFrame(byte[] data) {
int[] rgba = mRGBA;
FindFeatures(frameWidth, frameHeight, data, rgba);
Bitmap bmp = mBitmap;
bmp.setPixels(rgba, 0, frameWidth, 0, 0, frameWidth, frameHeight);
//samp.setValue(count++);
return bmp;
}
public native void FindFeatures(int width, int height, byte yuv[], int[] rgba);
}
So yeah, hope this helps. If I get the complete solution working, I'll post that also. Also post your stuff if you get the solution first please! Enjoy
Sry not a real answer (yet) but also tried to make a custom layout in opencv 2.4.2
i have this perfectly working solution for 2.4.0 if i remember it right it was enough to add the instructors.. but it doesn't work with 2.4.2
i'll try to figure smthg out and let you guys know.
I met the same problem that I wanted to create a custom view using layout. OpenCV 2.4.2 seems not to offer this function.
OpenCV 2.4.3 has the function, but its tutorial doesn't say so (it uses the old example from OpenCV2.4.2). Its Android samples provide some insights. Finally I found the instruction in OpenCV 2.4.9 documentation.
Hope it helps.
Hah, I figured out one way. You could just simply separate the OpenCV Loader and the custom layout.
Define BaseLoaderCallback mOpenCVCallBack.
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i(TAG, "OpenCV loaded successfully");
// Load native library after(!) OpenCV initialization
System.loadLibrary("native_sample");
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
In OnCreat, build your custom layout, load the OpenCv Loader,
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// /////////////////////////////////////////////////////////////////////
// // begin:
// // Create and set View
setContentView(R.layout.main);
mView = (Sample3View) findViewById(R.id.sample3view);
mcameraButton = (ImageView) findViewById(R.id.cameraButton);
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) {
Log.e(TAG, "Cannot connect to OpenCV Manager");
}
}
Just that!
I did that, and it worked very well.