Camera real time image processing - Android Q&A, Help & Troubleshooting

I need to do some image processing in real time on mobile. I am using camera2 library. I managed to put camera preview directly on surfaceView but when i redirect it to ImageReader to do something with frames before i preview them it goes really slow, and there is not even processing just taking Y value from YUV_420_888 and converting it to gray picture in ARGB_8888 format. Code is below. For that one for loop i need about 600ms. And for image processing i will need to go trough that image at least one more time. In Bits array i form ARGB_8888 format out of Y array which is Y value of YUV_420_888 format. I test it on phone with Quad Core 1ghz processor and 1gb ram. Is there any way to speed this code up so i can go lets say 2-3 times trough picture and have at least 7-10 fps? If i delete for loop and just measure fps its 8-12fps. Why is it so slow compering to 25fps when i put it directly on surfaceView?
Code:
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
// This method is called when the camera is opened. We start camera preview here.
mCameraOpenCloseLock.release();
mCameraDevice = cameraDevice;
createCameraPreviewSession();
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if(image != null) {
ByteBuffer buffer0 = image.getPlanes()[0].getBuffer();
byte[] Y = new byte[buffer0.remaining()];
buffer0.get(Y);
byte[] Bits = new byte[Y.length*4]; //That's where the RGBA array goes.
int Ylength = Y.length;
for (int i = 0; i < Ylength; i++) {
int i1 = i*4;
Bits[i1] =Y[i];
Bits[i1 + 1] =Y[i];
Bits[i1 + 2] = Y[i];
Bits[i1 + 3] = -1;//0xff, that's the alpha.
}
Bitmap bm = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(Bits));
Bitmap scaled = Bitmap.createScaledBitmap(bm, surfaceView.getWidth(), surfaceView.getHeight(), true);
Canvas c;
c = surfaceHolder.lockCanvas();
c.drawBitmap(scaled, 0, 0, null);
surfaceHolder.unlockCanvasAndPost(c);
image.close();
time2 = System.nanoTime();
Log.d("Vreme",Double.toString(1000000000/(time2-time1))+"fps");
time1 = System.nanoTime();
}
}
},mBackgroundHandler);
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
};

Related

[Q] How to use multi-threaded class in bootanimation?

Hi Droid-expert
For stock bootanimation in JB, there is a single threaded animation process/class inside. If I'd like to implement the power-on sound/tune as well. What's the best programming scheme/model it could be?
So far, by my understanding, I did something in BootAnimation.cpp in the following:
Did I do wrong? The handset boots up, it shows the animation first, and then the sound is played.
However, in a normal AOS adb shell session, try to run bootanimation, and it works fine (I mean both animation and sound are played at the same time)
Does the init is multi-threaded?
Anthony
class PlayerListener: public MediaPlayerListener, public Thread
{
public:
PlayerListener(): Thread(false), mp(NULL) {}
~PlayerListener() { delete mp; mp = NULL; }
virtual void notify(int, int, int, const Parcel *) {}
virtual bool threadLoop();
virtual status_t readyToRun();
private:
MediaPlayer* mp;
};
// ----------------------------------------------------------------------
bool PlayerListener::threadLoop()
{
if (mp != NULL)
mp->start();
sleep(100);
requestExit();
return false;
}
status_t PlayerListener::readyToRun()
{
int index = 7;
audio_devices_t device;
bool r;
mp = new MediaPlayer();
mp->setListener(this);
if (mp->setDataSource(SYSTEM_BOOTANIMATION_SOUND_FILE, NULL) == NO_ERROR) {
mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
mp->prepare();
mp->setLooping(false);
}
// AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index);
device = AudioSystem::getDevicesForStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
r = AudioSystem::setStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, index, device);
r = AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index, device);
if (index != 0) {
mp->seekTo(0);
// mp->start();
}
return NO_ERROR;
}
bool BootAnimation::threadLoop()
{
bool r;
sp<PlayerListener> player = new PlayerListener();
player->run("BootAnimatedMelody", PRIORITY_AUDIO);
if (mAndroidAnimation) {
r = android();
} else {
r = movie();
}

[Q] How do I filter a retrieve data in Spinner?

I'm new to android,stuck in this part of my code.
I do hope, someone would help me with it.
As ,I've stuck for quite a while and have to complete within 2 days,
If I would like to filter in spinner based on the dates, how should I do it? For example,
I've a list of events, and in my spinner
when I select "Today", it will show out the list for today.
I've tried out the coding, however, I met some error. The part in BOLD, ** is having error.
I would like to get the XML data from here:
[attached in this thread]
the highlighted part
here is my coding: AndroidXMLParsingActivity.java
public class AndroidXMLParsingActivity extends ListActivity implements OnItemSelectedListener {
String[] browseby;
String[] dates = { "Today", "Tomorrow", "Next Week",
};
ArrayList<String> browse = new ArrayList<String>();
ArrayList<String> mPostingData = new ArrayList<String>();
Spinner s1;
ListView listview;
CustomAdapter cus;
// All static variables
static final String URL = " URL ";
// XML node keys
static final String KEY_EVENT = "event"; // parent node
static final String KEY_TITLE = "title";
static final String KEY_START_TIME = "start_time";
@override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_EVENT);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
map.put(KEY_START_TIME, parser.getValue(e, KEY_START_TIME));
// adding HashList to ArrayList
menuItems.add(map);
}
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(this, menuItems,
R.layout.list_item, new String[] { KEY_TITLE,KEY_START_TIME }, new int[] {
R.id.title,
R.id.startTime });
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
@override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String title = ((TextView) view.findViewById(R.id.title))
.getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
SingleMenuItemActivity.class);
in.putExtra(KEY_TITLE, title);
startActivity(in);
}
});
listview = (ListView) findViewById(R.id.listView1);
s1 = (Spinner) findViewById(R.id.spinner1);
for (int i = 0; i < browseby.length; i++) {
browse.add(browseby);
}
// aa = new
// ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Category);
s1.setOnItemSelectedListener(this);
mPostingData = browse;
for (int i = 0; i < mPostingData.size(); i++) {
if (mPostingData.size() > 0)
Log.i("Datas", mPostingData.get(i));
}
cus = new CustomAdapter(this, 0);
setListAdapter(cus);
ArrayAdapter<String> aa = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, dates);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s1.setAdapter(aa);
}
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) {
// listview.setFilterText(Category[position]);
String Text = s1.getSelectedItem().toString();
cus.getFilter().filter(Text);
cus.notifyDataSetChanged();
}
public void onNothingSelected(AdapterView<?> parent) {
// listview.setFilterText("");
}
public void onListItemClick(ListView parent, View v, int position, long id) {
Toast.makeText(this, "You have selected " + mPostingData.get(position),
Toast.LENGTH_SHORT).show();
}
class CustomAdapter extends ArrayAdapter<String> {
public void setData(ArrayList<String> mPpst) {
mPostingData = mPpst;// contains class items data.
}
@override
******public Filter getFilter() {
return new Filter() {
@override
protected void publishResults(CharSequence constraint,
FilterResults start_time) {
if (start_time.equals("2013-09-25") {
setData((ArrayList<String>) start_time.values);
} else {
setData(browse);// set original values
}
notifyDataSetInvalidated();
}******
@override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (!TextUtils.isEmpty(constraint)) {
constraint = constraint.toString();
ArrayList<String> foundItems = new ArrayList<String>();
if (browse != null) {
for (int i = 0; i < browse.size(); i++) {
if (browse.get(i).contains(constraint)) {
System.out.println("My datas" + browse.get(i));
foundItems.add(browse.get(i));
} else {
}
}
}
result.count = foundItems.size();// search results found
// return count
result.values = foundItems;// return values
} else {
result.count = -1;// no search results found
}
return result;
}
};
}
LayoutInflater mInflater;
public CustomAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@override
public int getCount() {
// TODO Auto-generated method stub
return mPostingData.size();
}
@override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder vh;
if (convertView == null) {
vh = new ViewHolder();
convertView = mInflater.inflate(R.layout.row, null);
vh.t1 = (TextView) convertView.findViewById(R.id.textView1);
convertView.setTag(vh);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
vh = (ViewHolder) convertView.getTag();
}
if (mPostingData.size() > 0)
vh.t1.setText(mPostingData.get(position));
return convertView;
}
}
static class ViewHolder {
TextView t1;
}
}
randomise said:
I'm new to android,stuck in this part of my code.
I do hope, someone would help me with it.
As ,I've stuck for quite a while and have to complete within 2 days,
If I would like to filter in spinner based on the dates, how should I do it? For example,
I've a list of events, and in my spinner
when I select "Today", it will show out the list for today.
I've tried out the coding, however, I met some error. The part in BOLD, ** is having error.
I would like to get the XML data from here:
[attached in this thread]
the highlighted part
here is my coding: AndroidXMLParsingActivity.java
public class AndroidXMLParsingActivity extends ListActivity implements OnItemSelectedListener {
String[] browseby;
String[] dates = { "Today", "Tomorrow", "Next Week",
};
ArrayList<String> browse = new ArrayList<String>();
ArrayList<String> mPostingData = new ArrayList<String>();
Spinner s1;
ListView listview;
CustomAdapter cus;
// All static variables
static final String URL = " URL ";
// XML node keys
static final String KEY_EVENT = "event"; // parent node
static final String KEY_TITLE = "title";
static final String KEY_START_TIME = "start_time";
@override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_EVENT);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
map.put(KEY_START_TIME, parser.getValue(e, KEY_START_TIME));
// adding HashList to ArrayList
menuItems.add(map);
}
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(this, menuItems,
R.layout.list_item, new String[] { KEY_TITLE,KEY_START_TIME }, new int[] {
R.id.title,
R.id.startTime });
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
@override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String title = ((TextView) view.findViewById(R.id.title))
.getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
SingleMenuItemActivity.class);
in.putExtra(KEY_TITLE, title);
startActivity(in);
}
});
listview = (ListView) findViewById(R.id.listView1);
s1 = (Spinner) findViewById(R.id.spinner1);
for (int i = 0; i < browseby.length; i++) {
browse.add(browseby);
}
// aa = new
// ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Category);
s1.setOnItemSelectedListener(this);
mPostingData = browse;
for (int i = 0; i < mPostingData.size(); i++) {
if (mPostingData.size() > 0)
Log.i("Datas", mPostingData.get(i));
}
cus = new CustomAdapter(this, 0);
setListAdapter(cus);
ArrayAdapter<String> aa = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, dates);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s1.setAdapter(aa);
}
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) {
// listview.setFilterText(Category[position]);
String Text = s1.getSelectedItem().toString();
cus.getFilter().filter(Text);
cus.notifyDataSetChanged();
}
public void onNothingSelected(AdapterView<?> parent) {
// listview.setFilterText("");
}
public void onListItemClick(ListView parent, View v, int position, long id) {
Toast.makeText(this, "You have selected " + mPostingData.get(position),
Toast.LENGTH_SHORT).show();
}
class CustomAdapter extends ArrayAdapter<String> {
public void setData(ArrayList<String> mPpst) {
mPostingData = mPpst;// contains class items data.
}
@override
******public Filter getFilter() {
return new Filter() {
@override
protected void publishResults(CharSequence constraint,
FilterResults start_time) {
if (start_time.equals("2013-09-25") {
setData((ArrayList<String>) start_time.values);
} else {
setData(browse);// set original values
}
notifyDataSetInvalidated();
}******
@override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (!TextUtils.isEmpty(constraint)) {
constraint = constraint.toString();
ArrayList<String> foundItems = new ArrayList<String>();
if (browse != null) {
for (int i = 0; i < browse.size(); i++) {
if (browse.get(i).contains(constraint)) {
System.out.println("My datas" + browse.get(i));
foundItems.add(browse.get(i));
} else {
}
}
}
result.count = foundItems.size();// search results found
// return count
result.values = foundItems;// return values
} else {
result.count = -1;// no search results found
}
return result;
}
};
}
LayoutInflater mInflater;
public CustomAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@override
public int getCount() {
// TODO Auto-generated method stub
return mPostingData.size();
}
@override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder vh;
if (convertView == null) {
vh = new ViewHolder();
convertView = mInflater.inflate(R.layout.row, null);
vh.t1 = (TextView) convertView.findViewById(R.id.textView1);
convertView.setTag(vh);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
vh = (ViewHolder) convertView.getTag();
}
if (mPostingData.size() > 0)
vh.t1.setText(mPostingData.get(position));
return convertView;
}
}
static class ViewHolder {
TextView t1;
}
}
Click to expand...
Click to collapse
Can someone please help me out?
your help will be appreciated.
Thanks

[Q] Draw Objects on Screen

I'm starting to build an app that needs 2D drawing on Android Studio and even after some search I still have some troubles understanding some things. My intention is to draw Balls as objects, so that I can specify its radius and locations to draw. That ball should be a filled circle.
So here are my questions:
1. How to create the ball class in the most organized way? (Its constructors, methods, and stuff like that)​1. Where to call that class to create balls?(what should I do on the onCreate() method? My coding should go in my MainActivity class?)​1. How to draw them by a timer?(create a ball with a random radius and position and draw it on screen)​1. Where to draw them? (container)​
I saw a lot of things using canvas, the mysterious onDraw() method and I didn't get much of it.
I didn't understand how to control when to draw it.
I used this code for leaning and kinda control the drawing of objects , but It seems too messy and dont feel right.
Its a sensor controlled ball.
Bubbleview.java
Code:
public class BubbleView extends View
{
private int diametro;
private int x;
private int y;
private int Xt;
private int Yt;
private ShapeDrawable bubble;
private ShapeDrawable rect;
private boolean isTouch = false;
private int width;
private int height;
private WindowManager wm;
private Display display;
private Point size;
private Point centroBola;
private Point centroRet;
//private Color Retcor;
//private Color Bolacor;
public BubbleView(Context context)
{
super(context);
/*--Instancias--*/
bubble = new ShapeDrawable(new OvalShape());
rect = new ShapeDrawable(new RectShape());
size = new Point();
//Retcor = new Color();
//Bolacor = new Color();
createBubble();
}
private void createBubble()
{
wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
display = wm.getDefaultDisplay();
display.getSize(size);
width = (size.x);
height = (size.y);
x = width/2;
y = height/2;
//centroBola.set(x+(diametro/2),y-(diametro/2));
diametro = 100;
bubble.setBounds(x-diametro,y-diametro, x + diametro, y + diametro);
rect.setBounds(0, 10, size.x-1,80);
bubble.getPaint().setColor(0xff74AC23);
//rect.getPaint().setColor(0xff74AC23);//0xffEE4400
}
protected void move(float f, float g)
{
if (isTouch)
{
x = Xt;
y = Yt;
}
else
{
if (bubble.getBounds().right > width)
{
x=width-diametro-1;
y = (int) (y + g);
}
if (bubble.getBounds().left < 0)
{
x = 0;
y = (int) (y + g);
}
if (bubble.getBounds().top < 0)
{
x = (int) (x - f);
y = 1;
}
if (bubble.getBounds().bottom > height) {
x = (int) (x - f);
y = height - diametro -1;
}
x = (int) (x - f);
y = (int) (y + g);
}
//rect.setBounds(x+40, y+40, x + diametro, y + diametro);
bubble.setBounds(x,y,x +diametro,y+diametro);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
Xt = (int) event.getX();
Yt = (int) event.getY();
int evento = event.getAction();
switch (evento)
{
case MotionEvent.ACTION_DOWN:
bubble.setBounds(0, 0, Xt + diametro,Yt+ diametro);
//rect.setBounds(Xt, Yt, Xt + diametro,Yt+ diametro);
//coords.setText("X: " + X + ", Y: " + Y);
isTouch = true;
break;
case MotionEvent.ACTION_MOVE:
//coords.setText("X: " + X + ", Y: " + Y);
break;
case MotionEvent.ACTION_UP:
//Toast.makeText(this, "Saiu da tela em: X: " + X + ", Y: " + Y, Toast.LENGTH_SHORT);
isTouch = false;
break;
}
return true;
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
//rect.draw(canvas);
bubble.draw(canvas);
}
}
So I tried to build my app using this as a reference, but no success.
Wich way should the code becomes more intuitive?
thx in advance

Android Volley request weird “1 second” delay between multiple fast clicks

Sorry for my bad english, but i have problem and can't figure it out..
I have custom listview in my fragment for getting products from JSON array. And I have 3 ImageButtons in every listview row;
Plus Button(+), Minus Button(-) and Remove Button(X)..
So when i click each button, its calling JSON request for update product's piece number, getting new datas from response and repopulate array list.
Everything ok but, when I click that buttons faster, it seems there is 1 sec delay between multiple requests even first volley request has already done before.
Here is my JSON method in TableAdapter.java
Code:
[SIZE="3"]public void JSON(final int position, final int process) {
if (inProgress==false) {
dialog = new ProgressDialog(myContext);
dialog.setMessage("Updating.....");
dialog.show();
inProgress = true;
System.out.println("**** Now request is beginning............");
final int rowID = tableModelList.get(position).getID();
final int treeID = tableModelList.get(position).getAna_dal();
final float price = tableModelList.get(position).getBFiyat();
final int quantity = tableModelList.get(position).getAdet();
final int print = tableModelList.get(position).getYazdimi();
final String insertUrl = "This is URL for getting json array";
Map<String, String> parameters = new HashMap<>();
parameters.put("tableID", "" + getTableId);
parameters.put("rowID", "" + rowID);
parameters.put("treeID", ""+treeID);
parameters.put("process",""+process);
parameters.put("quantity",""+quantity);
parameters.put("price",""+price);
parameters.put("print",""+print);
CustomRequest jsObjRequest = new CustomRequest(Request.Method.POST, insertUrl, parameters, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray getOrders = response.getJSONArray("order");
Gson gson = new Gson();
tableModelList.clear();
for (int i = 0; i < getOrders.length(); i++) {
JSONObject order = getOrders.getJSONObject(i);
TableModel tableModel = gson.fromJson(order.toString(), TableModel.class);
tableModelList.add(tableModel);
}
mAdapter.notifyDataSetChanged();
System.out.println("**** onResponse: Request is done............");
System.out.println("**** JSON: "+response.toString());
dialog.cancel();
inProgress = false;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError response) {
Log.d("Response: ", response.toString());
inProgress = false;
}
});
requestQueue.add(jsObjRequest);
}
}[/SIZE]
Dialog is showing when request beginning and canceling when request is done. But as I said, when I click faster, there is a delay between multiple requests even first request has already done. I'm saying 1 sec, because 2nd request is beginning after 1 sec exactly, no matter how I clicking fast. I can't figure it out..
I tested fast clicks to showing toasts with random numbers and it's working fine. But when I testing with JSON method, there is a weird delay.
I have SwipeRefreshLayout and ScrollView in my fragment. I'm using Volley with singleton.
Here is video to showing what my problem is;
Here is Logcat output for every click
Every fast click has returning success json output, but nothing change instantly on the screen..
Thanks for your help.

Android VideoView Resize Algorithm - Bilinear or Bicubic?

Hi, community,
I was trying to resize a video to be played on Google Pixel 5 to fit the screen. I am able to achieve the required but I need to dig a bit deeper to understand the functioning under the hood. I want to understand if the resizing is happening on hardware or software? Also, what is the algorithm used in the resizing operation whether it is bilinear or bicubic or Lanczos or anything else?
Java:
public void setVideo(String id)
{
System.out.println("Starting video");
System.out.println(id);
String videoPath = Environment.getExternalStorageDirectory().getPath()+"/"+ id;
videoView.setVideoPath(videoPath);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
float screenProportion = (float) screenWidth / (float) screenHeight;
android.view.ViewGroup.LayoutParams lp = videoView.getLayoutParams();
int VideoWidth = mp.getVideoWidth();
int VideoHeight = mp.getVideoHeight();
float videoProportion = (float) VideoWidth / (float) VideoHeight;
if (videoProportion > screenProportion) {
lp.width = screenWidth;
lp.height = (int) ((float) screenWidth / videoProportion);
} else {
lp.width = (int) (videoProportion * (float) screenHeight);
lp.height = screenHeight;
}
videoView.setLayoutParams(lp);
}
});
videoView.start();

Categories

Resources