Android Display Images from directory - java

I am trying to display images from a specified directory on an android device in a gallery type activity. i was following (at least trying to) the guide on displaying images on the android developers site but kept getting lost http://developer.android.com/training/displaying-bitmaps/load-bitmap.html . I currently have a downsampled version of the image and am loading it into an image view in the layout.xml file. but this would require me to know the amount of images that will be present which i wont and i fear it is wasteful.
I need to Know how to create the image views depending on how many images are in the directory. and display the thumbnails or downsampled images in the created imageViews.
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView android:text="Hello World!" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/mImageView0"
android:layout_centerHorizontal="true"
android:layout_alignParentEnd="true" />
............
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/mImageView5"
android:layout_below="#id/mImageView4"
android:layout_centerHorizontal="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
private final String TAG = "MainActivity Class";
public ImageView mImageView;
public ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String fileDir = Environment.getExternalStorageDirectory().toString()+ File.separator +"Camera-App-Images"+ File.separator;
File f = new File(fileDir);
Log.d(TAG, fileDir);
File file[] = f.listFiles();
ImageView[] imgViews = new ImageView[file.length];
for (int i=0; i < file.length; i++) {
mImageView = (ImageView)findViewById(R.id.mImageView0 + i);
listView = (ListView)findViewById(R.id.listView);
loadBitmap(fileDir + file[i].getName(), mImageView);
}
}
public void loadBitmap(String fileLoc, ImageView imageView) {
BitmapWorkerTask task = new BitmapWorkerTask(fileLoc ,imageView);
task.execute();
}
}
BitmapWorkerTask
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
private String imagePath = "";
private final String TAG = "BitmapWorkerTask";
public BitmapWorkerTask(String imgPath, ImageView imageView) {
imagePath = imgPath;
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
Log.d(TAG,"Constructor");
}
// Decode image in background.
#Override
protected Bitmap doInBackground(Integer... params) {
//data = params[0];
return decodeSampledBitmapFromFile(imagePath, 100, 100);
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
public static Bitmap decodeSampledBitmapFromFile(String filePath, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}

Related

how can I get path list folder Android and set in Int Array.

I'm new in Android sorry....
I save any pictures in my App not SDCARD.
I use this code for get path but this code return String Array, I need return Int Array for my class CustomSwipeAdpter, this class for Page View.
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to data/data/yourapp/app_data/imageDir
new_folder = cw.getDir(pasta, Context.MODE_PRIVATE);
ArrayList<String> arquivos = new ArrayList<String> ();
if (!new_folder.exists()){
new_folder.mkdir();
}
// verifica a pasta se tem arquivo //
File[] files = new_folder.listFiles();
if ((files.length > 0)) {
String[] fileArray = new String[files.length];
int[] fileArrayInt = new int[files.length];
for (int i = 0; i < files.length; ++i) {
fileArray[i] = files[i].getAbsolutePath();
}
//filesResource[i] = Integer.parseInt(files[i].getAbsolutePath());
}
I will get this paths in this Class In Page View, this class is work with R.drawable.image01, i need change for my paths...
public class CustomSwipeAdpter extends PagerAdapter {
private int[] image_resources = {R.drawable.image01, R.drawable.image02, R.drawable.image03,
R.drawable.image04, R.drawable.image05, R.drawable.image06, R.drawable.image07, R.drawable.image08};
private Context ctx;
private LayoutInflater layoutInflater;
private Resources resource;
public CustomSwipeAdpter(Context ctx) {
this.ctx = ctx;
resource = ctx.getResources();
}
#Override
public int getCount() {
return image_resources.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view == (LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position){
layoutInflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View item_view = layoutInflater.inflate(R.layout.swipe_layout, container, false);
ImageView imageView = (ImageView) item_view.findViewById(R.id.imageView);
imageView.setImageBitmap(
decodeSampledBitmapFromResource(resource,
image_resources[position],
1080,
2560));
container.addView(item_view);
return item_view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 2;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
This class is fine when i use:
private int[] image_resources = {R.drawable.image01, R.drawable.image02, R.drawable.image03,
R.drawable.image04, R.drawable.image05, R.drawable.image06, R.drawable.image07, R.drawable.image08};
I need set this image_resources the my path.
May you could try follow way instead of resources:
Bitmap bitmap = BitmapFactory.decodeFile(fileArray[position]);

How can i set alignment of horizontalScrollView of images

I have created list of images in horizontal fashion using horizontalscrollview its working fine but i want to show last image always because its capturing image.
My Layout
<HorizontalScrollView
android:id="#+id/horizontal_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.activities.MyHorizontalLayout
android:id="#+id/linear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
/>
</HorizontalScrollView>
HorizontalScrollView Class
public class MyHorizontalLayout extends LinearLayout {
Context myContext;
ArrayList<String> itemList = new ArrayList<String>();
public Bitmap selectedbm;
public static String selectedfile;
public MyHorizontalLayout(Context context) {
super(context);
myContext = context;
}
public MyHorizontalLayout(Context context, AttributeSet attrs) {
super(context, attrs);
myContext = context;
}
public MyHorizontalLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
myContext = context;
}
void add(String path) {
int newIdx = itemList.size();
itemList.add(path);
addView(getImageView(newIdx));
}
void remove(String path,int ind) {
removeView(getImageView(ind));
itemList.remove(ind);
}
ImageView getImageView(final int i) {
Bitmap bm = null;
if (i < itemList.size()) {
bm = decodeSampledBitmapFromUri(itemList.get(i), 220, 220);
}
ImageView imageView = new ImageView(myContext);
imageView.setLayoutParams(new LayoutParams(180, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(bm);
/*ImageGalleryEdit.edit.setVisibility(View.GONE);
ImageGalleryEdit.delete.setVisibility(View.GONE);
*/
ImageGalleryEdit.viewimg.setImageBitmap(decodeSampledBitmapFromUri(itemList.get(i), 1220, 1220));
selectedfile = itemList.get(i);
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageGalleryEdit.edit.setVisibility(View.VISIBLE);
ImageGalleryEdit.delete.setVisibility(View.VISIBLE);
ImageGalleryEdit.viewimg.setImageBitmap(decodeSampledBitmapFromUri(itemList.get(i), 1220, 1220));
selectedbm = decodeSampledBitmapFromUri(itemList.get(i), 1220, 1220);
selectedfile = itemList.get(i);
}
});
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth,
int reqHeight) {
Bitmap bm = null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
}
Try to use fullScroll properties after fill data to horizontalscrollview :
hs.postDelayed(new Runnable() {
public void run() {
hs.fullScroll(View.FOCUS_RIGHT);
}
}, 100);

Error on cropping a custom shape image

(JAVA FILE 1)
public class CropActivity extends Activity implements OnTouchListener {
public static final String RETURN_DATA = "return-data";
public static final String RETURN_DATA_AS_BITMAP = "data";
public static final String ACTION_INLINE_DATA = "inline-data";
private ImageView mImg;
private ImageView mTemplateImg;
// private static ProgressDialog mProgressDialog;
private Matrix mMatrix = new Matrix();
private float mScaleFactor = 0.8f;
private float mRotationDegrees = 0.f;
private float mFocusX = 0.f;
private float mFocusY = 0.f;
private int mImageHeight, mImageWidth;
private ScaleGestureDetector mScaleDetector;
private MoveGestureDetector mMoveDetector;
// Constants
public static final int MEDIA_GALLERY = 1;
public static final int TEMPLATE_SELECTION = 2;
public static final int DISPLAY_IMAGE = 3;
Bitmap profilePic;
String userImageLink;
int cropImageWidth;
int cropImageHeight;
int width, height, w1;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.crop_activity_layout);
Resources r = getResources();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
width = dm.widthPixels;
height = dm.heightPixels;
double fWidth = width * (0.70);
Log.d("Width is:- ", ">>>>>>>>>>>>>>>>" + fWidth);
w1 = (int) Math.round(fWidth);
Log.d("Width after roundin is:- ", ">>>>>>>>>>>>>>>>" + width);
cropImageWidth = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, w1, r.getDisplayMetrics());
// etc...
cropImageHeight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, w1, r.getDisplayMetrics());
int actionBarHeight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 40, r.getDisplayMetrics());
userImageLink = getIntent().getStringExtra("path");
mImg = (ImageView) findViewById(R.id.cp_img);
mTemplateImg = (ImageView) findViewById(R.id.cp_face_template);
mImg.setOnTouchListener(this);
// Get screen size in pixels.
// DisplayMetrics metrics = new DisplayMetrics();
// getWindowManager().getDefaultDisplay().getMetrics(metrics);
// mScreenWidth = metrics.widthPixels;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int statusBarHeight = (int) Math.ceil(25 * (getResources()
.getDisplayMetrics().density));
Log.e("size.x", "" + size.x);
Log.e("size.y", "" + (size.y - statusBarHeight - actionBarHeight));
// Set template image accordingly to device screen size.
Bitmap faceTemplate = BitmapFactory.decodeResource(getResources(),
R.drawable.four);
faceTemplate = Bitmap.createScaledBitmap(faceTemplate, cropImageWidth,
cropImageHeight, true);
mTemplateImg.setImageBitmap(faceTemplate);
// cropImageWidth = faceTemplate.getWidth();
// cropImageHeight = faceTemplate.getHeight();
// Log.e("getWidth", "" + faceTemplate.getWidth());
// Log.e("getHeight", "" + faceTemplate.getHeight());
File imgFile = new File("" + userImageLink);
if (imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile
.getAbsolutePath());
// Drawable d = new BitmapDrawable(getResources(), myBitmap);
mImg.setImageBitmap(myBitmap);
mImageHeight = myBitmap.getHeight();
mImageWidth = myBitmap.getWidth();
}
// View is scaled by matrix, so scale initially
mMatrix.postScale(mScaleFactor, mScaleFactor);
mImg.setImageMatrix(mMatrix);
// Setup Gesture Detectors
mScaleDetector = new ScaleGestureDetector(getApplicationContext(),
new ScaleListener());
mMoveDetector = new MoveGestureDetector(getApplicationContext(),
new MoveListener());
// Instantiate Thread Handler.
// mCropHandler = new CropHandler(this);
}
public void onCancelImageButton(View v) {
Intent intent = new Intent();
setResult(RESULT_CANCELED, intent);
finish();
}
public void onCropImageButton(View v) {
// Create progress dialog and display it.
// mProgressDialog = new ProgressDialog(v.getContext());
// mProgressDialog.setCancelable(false);
// mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
// mProgressDialog.setMessage("Please wait...");
// mProgressDialog.show();
// Setting values so that we can retrive the image from
// ImageView multiple times.
mImg.buildDrawingCache(true);
mImg.setDrawingCacheEnabled(true);
mTemplateImg.buildDrawingCache(true);
mTemplateImg.setDrawingCacheEnabled(true);
// Create new thread to crop.
new Thread(new Runnable() {
#Override
public void run() {
Bitmap croppedImg = null;
croppedImg = ImageProcess.cropImage(mImg.getDrawingCache(true),
mTemplateImg.getDrawingCache(true), cropImageWidth,
cropImageHeight);
mImg.setDrawingCacheEnabled(false);
mTemplateImg.setDrawingCacheEnabled(false);
if (croppedImg != null) {
// mProgressDialog.dismiss();
Utils.storeImage(croppedImg, "temp" + Const.ImageExtension);
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
} else {
// mProgressDialog.dismiss();
Intent intent = new Intent();
setResult(RESULT_CANCELED, intent);
finish();
}
}
}).start();
}
#SuppressLint("ClickableViewAccessibility")
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
mMoveDetector.onTouchEvent(event);
float scaledImageCenterX = (mImageWidth * mScaleFactor) / 2;
float scaledImageCenterY = (mImageHeight * mScaleFactor) / 2;
mMatrix.reset();
mMatrix.postScale(mScaleFactor, mScaleFactor);
mMatrix.postRotate(mRotationDegrees, scaledImageCenterX,
scaledImageCenterY);
mMatrix.postTranslate(mFocusX - scaledImageCenterX, mFocusY
- scaledImageCenterY);
ImageView view = (ImageView) v;
view.setImageMatrix(mMatrix);
return true;
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));
return true;
}
}
private class MoveListener extends
MoveGestureDetector.SimpleOnMoveGestureListener {
#Override
public boolean onMove(MoveGestureDetector detector) {
PointF d = detector.getFocusDelta();
mFocusX += d.x;
mFocusY += d.y;
return true;
}
}
}
(JAVA FILE 2)
public class ImageProcess {
public static Bitmap cropImage(Bitmap img, Bitmap templateImage, int width,
int height) {
// Merge two images together.
Bitmap bm = Bitmap.createBitmap(img.getWidth(), img.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas combineImg = new Canvas(bm);
combineImg.drawBitmap(img, 0f, 0f, null);
// Create new blank ARGB bitmap.
Bitmap finalBm = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
// Get the coordinates for the middle of combineImg.
int hMid = bm.getHeight() / 2;
int wMid = bm.getWidth() / 2;
int hfMid = finalBm.getHeight() / 2;
int wfMid = finalBm.getWidth() / 2;
finalBm = Bitmap.createBitmap(bm, (wMid - wfMid), (hMid - hfMid),
width, height);
// Get rid of images that we finished with to save memory.
img.recycle();
templateImage.recycle();
bm.recycle();
return finalBm;
}
}
(XML FILE 1)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<innovify.hustl.library.CustomTextView
android:id="#+id/fcp_info_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/cp_info_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1.0" >
<ImageView
android:id="#+id/cp_img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:contentDescription="#string/cp_image_contentDesc"
android:scaleType="matrix" />
<ImageView
android:id="#+id/cp_face_template"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:contentDescription="#string/cp_template_contentDesc"
android:scaleType="centerInside"
android:src="#drawable/four" />
</FrameLayout>
<LinearLayout
style="?android:attr/buttonBarStyle"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:orientation="horizontal" >
<innovify.hustl.library.CustomButton
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="#e2e2e2"
android:gravity="center"
android:onClick="onCancelImageButton"
android:text="#string/cancel" />
<innovify.hustl.library.CustomButton
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="#e2e2e2"
android:gravity="center"
android:onClick="onCropImageButton"
android:text="#string/cp_crop_button" />
</LinearLayout>
Output:
Got This Error:-
12-08 13:35:38.108: E/AndroidRuntime(15191): FATAL EXCEPTION: Thread-1317
12-08 13:35:38.108: E/AndroidRuntime(15191): java.lang.IllegalArgumentException: x must be >= 0
12-08 13:35:38.108: E/AndroidRuntime(15191): at android.graphics.Bitmap.checkXYSign(Bitmap.java:280)
12-08 13:35:38.108:
for custom shape in imageview,
you can use this lib
https://github.com/siyamed/android-shape-imageview
https://github.com/MostafaGazar/CustomShapeImageView

How to resize input image

How to resize 2 images in android , as one image which remain constant ( .png image in drawable folder) should be equal to the size of input image (image enter from the user from mobile gallery) . I use resize(src, dst) function in opencv for resizing two images , don't have any idea of this kind of function in java end as I check this post as well but it look some kind of extra loaded work to me.
I know some method about image operation in android.
Transform Drawable to Bitmap:
public static Bitmap drawableToBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
Resize Bitmap:
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
matrix, true);
return newbmp;
}
You can transform your first Drawable image to Bitmap, then resize it with the second method. Use getWidth() and getHeight() to get parameters of the image.
I don't know whether this is the best solution. If I didn't understand your intent well, make a comment and I can edit my answer.
Edit:
You can get Uri or the path of the image right?
If you get Uri, use String path = uri.getPath(); to get the path.
Then
Decode Bitmap from file:
public static Bitmap getBitmap(String path) {
return BitmapFactory.decodeFile(String path);
}
If the size of image is not too big, load it directly wouldn't cause memory leaks, everything is OK.
But if you don't know the size, I recommend the next method.
Decode BitmapDrawable from path:
public static BitmapDrawable getScaledDrawable(Activity a, String path) {
Display display = a.getWindowManager().getDefaultDisplay();
float destWidth = display.getWidth();
float destHeight = display.getHeight();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
int inSampleSize = 1;
if (srcHeight > destHeight || srcWidth > destWidth) {
if (srcWidth > srcHeight) {
inSampleSize = Math.round(srcHeight / destHeight);
} else {
inSampleSize = Math.round(srcWidth / destWidth);
}
}
options = new BitmapFactory.Options();
options.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
return new BitmapDrawable(a.getResources(), bitmap);
}
This method will return a scaled BitmapDrawable object to prevent memory leaks.
If you need Bitmap not BitmapDrawable , just return bitmap.
Edit2:
ThirdActivity.java :
public class ThirdActivity extends ActionBarActivity {
private static final int REQUEST_IMAGE = 0;
private Bitmap bitmapToResize;
private Button mGetImageButton;
private Button mResizeButton;
private ImageView mImageViewForGallery;
private ImageView mImageVIewForDrable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
mGetImageButton = (Button) findViewById(R.id.button_getImage);
mGetImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// SET action AND miniType
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
// REQUEST Uri of image
startActivityForResult(intent, REQUEST_IMAGE);
}
});
mResizeButton = (Button) findViewById(R.id.button_resize);
mResizeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
resize();
}
});
mImageViewForGallery = (ImageView) findViewById(R.id.imageView);
mImageVIewForDrable = (ImageView) findViewById(R.id.imageViewFromDrable);
mImageVIewForDrable.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {return;}
if (requestCode == REQUEST_IMAGE) {
Uri uri = data.getData();
// SET image
mImageViewForGallery.setImageURI(uri);
Drawable drawable = mImageViewForGallery.getDrawable();
Log.e("asd", "Height:" + drawable.getIntrinsicHeight());
Log.e("asd", "Width:" + drawable.getIntrinsicWidth());
}
}
private void resize() {
if (mImageViewForGallery.getDrawable() != null) {
bitmapToResize = drawableToBitmap(mImageVIewForDrable.getDrawable());
int width = mImageViewForGallery.getDrawable().getIntrinsicWidth();
int height = mImageViewForGallery.getDrawable().getIntrinsicHeight();
bitmapToResize = zoomBitmap(bitmapToResize, width, height);
mImageVIewForDrable.setImageBitmap(bitmapToResize);
} else {
Log.e("asd", "setImageFirst");
}
}
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
matrix, true);
return newbmp;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
}
activity_third.xml:
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:background="#android:color/darker_gray"
tools:context="com.ch.summerrunner.ThirdActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray">
<Button
android:id="#+id/button_getImage"
android:text="#string/gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/button_resize"
android:text="#string/resize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_toRightOf="#id/button_getImage"/>
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#android:color/white"
android:layout_below="#id/button_getImage"/>
<ImageView
android:id="#+id/imageViewFromDrable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:layout_below="#id/imageView"/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
Bitmap bmpIn = BitmapFactory.decodeResource(view.getResources(), R.drawable.image);
BitMap bmpOut = Bitmap.createScaledBitmap(bmpIn, width, height, false);

Full screen videoview without stretching the video

I wonder if I can get a way to let video run via videoview in full screen?
I searched a lot and tried many ways such as:
Apply theme in manifest:
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
but that does not force the video to be in full screen.
Apply in activity itself:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
also does not force the video to be in full screen.
The only way force video to full screen is:
<VideoView android:id="#+id/myvideoview"
android:layout_width="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_height="fill_parent">
</VideoView>
This way it results in full screen video but it stretches the video itself (elongated video) ,
I'm not applying this improper solution to my videoview, so is there is any way to do it without stretching the video?
Video Class:
public class Video extends Activity {
private VideoView myvid;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
myvid = (VideoView) findViewById(R.id.myvideoview);
myvid.setVideoURI(Uri.parse("android.resource://" + getPackageName()
+"/"+R.raw.video_1));
myvid.setMediaController(new MediaController(this));
myvid.requestFocus();
myvid.start();
}
}
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<VideoView
android:id="#+id/myvideoview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Like this you can set the properties of the video by yourself.
Use a SurfaceView (gives you more control on the view), set it to fill_parent to match the whole screen
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="#+id/surfaceViewFrame"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" >
</SurfaceView>
</Linearlayout>
then on your java code get the surface view and add your media player to it
surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
player = new MediaPlayer();
player.setDisplay(holder);
set on your media player a onPreparedListener and manually calculate the desired size of the video, to fill the screen in the desired proportion avoiding stretching the video!
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// Adjust the size of the video
// so it fits on the screen
int videoWidth = player.getVideoWidth();
int videoHeight = player.getVideoHeight();
float videoProportion = (float) videoWidth / (float) videoHeight;
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
float screenProportion = (float) screenWidth / (float) screenHeight;
android.view.ViewGroup.LayoutParams lp = surfaceViewFrame.getLayoutParams();
if (videoProportion > screenProportion) {
lp.width = screenWidth;
lp.height = (int) ((float) screenWidth / videoProportion);
} else {
lp.width = (int) (videoProportion * (float) screenHeight);
lp.height = screenHeight;
}
surfaceViewFrame.setLayoutParams(lp);
if (!player.isPlaying()) {
player.start();
}
}
});
I modified this from a tutorial for video streaming that I followed some time ago, can't find it right now to reference it, if someone does please add the link to the answer!
Hope it helps!
EDIT
Ok, so, if you want the video to occupy the whole screen and you don't want it to stretch you will end up with black stripes in the sides. In the code I posted we are finding out what is bigger, the video or the phone screen and fitting it the best way we can.
There you have my complete activity, streaming a video from a link. It's 100% functional. I can't tell you how to play a video from your own device because I don't know that. I'm sure you will find it in the documentation here or here.
public class VideoPlayer extends Activity implements Callback, OnPreparedListener, OnCompletionListener,
OnClickListener {
private SurfaceView surfaceViewFrame;
private static final String TAG = "VideoPlayer";
private SurfaceHolder holder;
private ProgressBar progressBarWait;
private ImageView pause;
private MediaPlayer player;
private Timer updateTimer;
String video_uri = "http://daily3gp.com/vids/familyguy_has_own_orbit.3gp";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videosample);
pause = (ImageView) findViewById(R.id.imageViewPauseIndicator);
pause.setVisibility(View.GONE);
if (player != null) {
if (!player.isPlaying()) {
pause.setVisibility(View.VISIBLE);
}
}
surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
surfaceViewFrame.setOnClickListener(this);
surfaceViewFrame.setClickable(false);
progressBarWait = (ProgressBar) findViewById(R.id.progressBarWait);
holder = surfaceViewFrame.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
player = new MediaPlayer();
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setScreenOnWhilePlaying(true);
player.setDisplay(holder);
}
private void playVideo() {
new Thread(new Runnable() {
public void run() {
try {
player.setDataSource(video_uri);
player.prepare();
} catch (Exception e) { // I can split the exceptions to get which error i need.
showToast("Error while playing video");
Log.i(TAG, "Error");
e.printStackTrace();
}
}
}).start();
}
private void showToast(final String string) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(VideoPlayer.this, string, Toast.LENGTH_LONG).show();
finish();
}
});
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
playVideo();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
//prepare the video
public void onPrepared(MediaPlayer mp) {
progressBarWait.setVisibility(View.GONE);
// Adjust the size of the video
// so it fits on the screen
int videoWidth = player.getVideoWidth();
int videoHeight = player.getVideoHeight();
float videoProportion = (float) videoWidth / (float) videoHeight;
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
float screenProportion = (float) screenWidth / (float) screenHeight;
android.view.ViewGroup.LayoutParams lp = surfaceViewFrame.getLayoutParams();
if (videoProportion > screenProportion) {
lp.width = screenWidth;
lp.height = (int) ((float) screenWidth / videoProportion);
} else {
lp.width = (int) (videoProportion * (float) screenHeight);
lp.height = screenHeight;
}
surfaceViewFrame.setLayoutParams(lp);
if (!player.isPlaying()) {
player.start();
}
surfaceViewFrame.setClickable(true);
}
// callback when the video is over
public void onCompletion(MediaPlayer mp) {
mp.stop();
if (updateTimer != null) {
updateTimer.cancel();
}
finish();
}
//pause and resume
public void onClick(View v) {
if (v.getId() == R.id.surfaceViewFrame) {
if (player != null) {
if (player.isPlaying()) {
player.pause();
pause.setVisibility(View.VISIBLE);
} else {
player.start();
pause.setVisibility(View.GONE);
}
}
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView1 = (VideoView) findViewById(R.id.videoview);
String SrcPath = "/mnt/sdcard/final.mp4";
videoView1.setVideoPath(SrcPath);
videoView1.setMediaController(new MediaController(this));
videoView1.requestFocus();
videoView1.start();
}
}
<VideoView
android:id="#+id/videoview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</VideoView>
try this it's working for me
The current upvoted solution works, but there may be a simpler solution to the original problem. A commenter correctly pointed out that you could resize a VideoView using the same methodology without the cost of converting everything to a SurfaceView. I tested this in one of my apps and it seems to work. Just add the calculated layout parameters to the VideoView in the OnPreparedListener callback:
mInspirationalVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// mMediaPlayer = mp;
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
#Override
public void onSeekComplete(MediaPlayer mp) {
if(isPlaying = true) {
stopPosition = 0;
mp.start();
mVideoProgressTask = new VideoProgress();
mVideoProgressTask.execute();
}
}
});
// so it fits on the screen
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
float videoProportion = (float) videoWidth / (float) videoHeight;
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
float screenWidth = mDisplayMetrics.widthPixels;
float screenHeight = mDisplayMetrics.heightPixels;
float screenProportion = (float) screenWidth / (float) screenHeight;
android.view.ViewGroup.LayoutParams lp = mInspirationalVideoView.getLayoutParams();
if (videoProportion > screenProportion) {
lp.width = screenWidth;
lp.height = (int) ((float) screenWidth / videoProportion);
} else {
lp.width = (int) (videoProportion * (float) screenHeight);
lp.height = screenHeight;
}
mInspirationalVideoView.setLayoutParams(lp);
...
}
});
Here is my function which works for the full screen video without stretching it. It will automatically crop the sides of the video. It worked both portrait and landscape modes.
It was actually taken from the answer.
public void onPrepared(MediaPlayer mp) {
int videoWidth = mediaPlayer.getVideoWidth();
int videoHeight = mediaPlayer.getVideoHeight();
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
float scaleY = 1.0f;
float scaleX = (videoWidth * screenHeight / videoHeight) / screenWidth;
int pivotPointX = (int) (screenWidth / 2);
int pivotPointY = (int) (screenHeight / 2);
surfaceView.setScaleX(scaleX);
surfaceView.setScaleY(scaleY);
surfaceView.setPivotX(pivotPointX);
surfaceView.setPivotY(pivotPointY);
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
Have you tried adjusting the underlying surface holder size? Try the code below it should adjust the surface holder to be the same width and height of the screen size. You should still have your activity be full screen without a title bar.
public class Video extends Activity {
private VideoView myvid;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
myvid = (VideoView) findViewById(R.id.myvideoview);
myvid.setVideoURI(Uri.parse("android.resource://" + getPackageName()
+"/"+R.raw.video_1));
myvid.setMediaController(new MediaController(this));
myvid.requestFocus();
//Set the surface holder height to the screen dimensions
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
myvid.getHolder().setFixedSize(size.x, size.y);
myvid.start();
}
}
Well, I hope it helps FullscreenVideoView
It handles all boring code about surfaceView and fullscreen view and let you focus only in UI buttons.
And you can use the FullscreenVideoLayout if you don't want to build your custom buttons.
A SurfaceView gives u an optimized drawing surface
public class YourMovieActivity extends Activity implements SurfaceHolder.Callback {
private MediaPlayer media = null;
//...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
media = new MediaPlayer();
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
//...
}
}
MediaPlayer calls should be wrapped in a try{}.
#Override
public void surfaceCreated(SurfaceHolder holder) {
media.setDataSource("android.resource://" + getPackageName()
+"/"+R.raw.video_);
media.prepare();
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
android.view.
ViewGroup.LayoutParams layout = mSurfaceView.getLayoutParams();
layout.width = screenWidth;
layout.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth);
mSurfaceView.setLayoutParams(layout);
mp.start();
}
I have solved this one by Custom VideoView:
I have added VideoView to ParentView in two ways From xml & programatically.
Add Custom class for VideoView named with FullScreenVideoView.java:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;
public class FullScreenVideoView extends VideoView {
public FullScreenVideoView(Context context) {
super(context);
}
public FullScreenVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FullScreenVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
How to bind with xml:
<FrameLayout
android:id="#+id/secondMedia"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.my.package.customview.FullScreenVideoView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fullScreenVideoView"/>
</FrameLayout>
OR
How to add Programatically VideoView to ParentView:
FullScreenVideoView videoView = new FullScreenVideoView(getActivity());
parentLayout.addView(videoView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
Hope this will help you.

Categories