I'm trying to load an image from my res/drawable folder.I used the guide from Android Developers Link.
For some reason it isnt working.The only error I get is "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length",which I researched.Appearently it has to do with custom keyboards but I'm not using text input at all.The app itself isnt crashing.I hope you guys can help me :)
The layout file just contains a RelativeLayout with an ImageView.
public class PixelActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pixel);
String uri = "#drawable-hdpi/testbild.png";
final int imageResource = getResources().getIdentifier(uri, null, getPackageName());
final ImageView iv = (ImageView) findViewById(R.id.imageview1);
//int imageHeight = options.outHeight;
//int imageWidth = options.outWidth;
//String imageType = options.outMimeType;
new Thread(new Runnable()
{
public void run()
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), imageResource, options);
iv.post(new Runnable()
{
public void run()
{
iv.setImageBitmap(decodeSampledBitmapFromResources(getResources(),imageResource,iv.getWidth(),iv.getHeight()));
//iv.setImageResource(R.drawable.testbild);
}
});
}
});
}
public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight)
{
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if(height > reqHeight || width > reqWidth)
{
final int heightRatio = Math.round((float)height/(float)reqHeight);
final int widthRatio = Math.round((float)width/(float)reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResources(Resources res, int resId, int reqWidth, int reqHeight)
{
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
}
String uri = "#drawable-hdpi/testbild.png";
That is invalid. Delete the -hdpi portion and the .png portion, and try again. Or, switch to providing all three parameters to getIdentifier():
final int imageResource = getResources().getIdentifier("testbild", "drawable", getPackageName());
Related
I am loading images from URL and showing on the imageview at runtime.
My problem is sometimes my images are shown only HALF OF THE IMAGE and rest part of the image is shown white. Have read many posts on the net but none of them has helped me in the same..
Kindly provide a good solution for the same and the real cause.
Here is the code I have used to create the bitmap.
public static Bitmap getBitmapFromCard(String path, int reqWidth,
int reqHeight) {
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
} catch (OutOfMemoryError e) {
System.gc();
System.gc();
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = 3;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
}
Calculation - InSampleSize
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 heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
Screenshot attached.
I want to load large Bitmap image in the Imageview.I am follow the code from Loading Large Bitmaps Efficiently .It's shown for single imageView.But I want to pick images from gallery for dynamic ImageView.I try to get the id of the picked Image and set decodeSampledBitmapFromResouce.It's set the Empty in the ImageView.Please help me to solve the Issue.Any help I'm very appreciated.Please see my code Below.
Button loadImg;
ImageView myImageView;
InputStream imageStream;
Bitmap productIndex = null;
private static int RESULT_LOAD_IMAGE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadImg = (Button)findViewById(R.id.btnPickImage);
myImageView = (ImageView) findViewById(R.id.myImgView);
loadImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,RESULT_LOAD_IMAGE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
myImageView = (ImageView) findViewById(R.id.myImgView);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picturePath, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
// here I set the bitmap to ImageView but the Image is not shown
int picId = getResources().getIdentifier(picturePath, "drawable", getApplicationContext().getPackageName());
myImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(),picId,100,100));
}
}
public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight) {
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 ((halfWidth / inSampleSize) > reqWidth && (halfHeight / inSampleSize) > reqHeight) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId,int reqWidth,int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res,resId,options);
/* Calculate inSampleSize */
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res,resId,options);
}
Try this.
public static Bitmap decodeSampledBitmapFromFile(File f, int reqWidth, int reqHeight) { // BEST QUALITY MATCH
String path = f.getAbsolutePath();
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
// Raw height and width of background
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float) height / (float) reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth) {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
// Correct rotation
ExifInterface exif = null;
try {
exif = new ExifInterface(f.getPath());
} catch (IOException e) {
e.printStackTrace();
}
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
Matrix matrix = new Matrix();
if (rotation != 0f) {
matrix.preRotate(rotationInDegrees);
}
Bitmap output = BitmapFactory.decodeFile(path, options);
if (output != null) {
return Bitmap.createBitmap(output, 0, 0, output.getWidth(), output.getHeight(), matrix, false);
} else {
return null;
}
}
public static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
I followed the online tutorial and created a class like so:
public class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
#Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return decodeSampledBitmapFromResource(getResources(), data, 100, 100);
}
public 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 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;
// 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;
}
// 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 void loadBitmap(int resId, ImageView imageView) {
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(resId);
}
}
Now that I created the "ASyncTask" class, I do not know how to apply it.
What I need to do is simple. I need to draw the bitmap like so (it is set up so that it will do it every second):
canvas.drawBitmap(myBitmap, centerX, centerY, null);
How do I apply ASyncTask now so that I will draw this bitmap without doing too much work on the thread? Please help, much appreciated.
When i was loading images form sd card i got the exception
java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
Here is my code:
public class Images extends Activity implements OnItemLongClickListener {
private Uri[] mUrls;
String[] mFiles = null;
ImageView selectImage;
Gallery g;
static final String MEDIA_PATH = new String("/mnt/sdcard/DCIM/Camera/");
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
selectImage = (ImageView) findViewById(R.id.image);
g = (Gallery) findViewById(R.id.gallery);
File images = new File(MEDIA_PATH);
Log.i("files", images.getAbsolutePath());
File[] imagelist = images.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return ((name.endsWith(".jpg")) || (name.endsWith(".png")));
}
});
Log.i("files", imagelist.toString());
String[] mFiles = null;
mFiles = new String[imagelist.length];
for (int i = 0; i < imagelist.length; i++) {
mFiles[i] = imagelist[i].getAbsolutePath();
}
System.out.println(mFiles.length);
mUrls = new Uri[mFiles.length];
System.out.println(mUrls.length);
for (int i = 0; i < mFiles.length; i++) {
mUrls[i] = Uri.parse(mFiles[i]);
}
g.setAdapter(new ImageAdapter(this));
// g.setOnItemSelectedListener(this);
g.setOnItemLongClickListener(this);
}
public class ImageAdapter extends BaseAdapter {
// int mGalleryItemBackground;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mUrls.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
Log.i("ok5", "ok");
ImageView i = new ImageView(mContext);
i.setImageURI(mUrls[position]);
Log.i("ok", "ok");
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
i.setLayoutParams(new Gallery.LayoutParams(100, 100));
return i;
}
private Context mContext;
}
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
selectImage.setImageURI(mUrls[arg2]);
System.out.println("path: "+mUrls[arg2]);
Uri f = mUrls[arg2];
File f1 = new File(f.toString());
System.out.println("f1: "+f1);
return false;
}
While you load large bitmap files, BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(), decodeResource(), etc.).
STEP 1
Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data prior to construction (and memory allocation) of the bitmap.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it.
STEP 2
To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to true in your BitmapFactory.Options object.
For example, an image with resolution 2048x1536 that is decoded with an inSampleSize of 4 produces a bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full image.
Here’s a method to calculate a sample size value that is a power of two based on a target width and height:
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 = 1;
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;
}
Please read this link for details. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
in my App I need to scale an image, this works with normaly. But when a big pictured will be
loaded then the decodeStream method returns null. Currently it does not work when the image was bigger than 6 MB (5616x3744)
Does someone know why this happens and what can i do to fix this?
public static Bitmap scaleImage(final String filepath, int height, int width) throws IOException{
if (filepath == null){
Log.e(TAG, "cannot create Thumbnail without file");
return null;
}
File f = new File(filepath);
InputStream is = new FileInputStream(f);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
is.close();
final int imageHeight = options.outHeight;
final int imageWidth = options.outWidth;
String imageType = options.outMimeType;
final int thumbnailHeight = height;
final int thumbnailWidth = width;
int heightRatio = Math.round((float) imageHeight) / Math.round((float) thumbnailHeight);
int widthRatio = Math.round((float) imageWidth) / Math.round((float) thumbnailWidth);
int inSampleSize = 0;
if (heightRatio < widthRatio){
inSampleSize = heightRatio ;
}
else{
inSampleSize = widthRatio;
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
int retrySteps = 0;
InputStream is2 = new FileInputStream(f);
Bitmap bmp = null;
for (int i = 0; i < 5; i++){
options.inJustDecodeBounds = false;
try {
bmp = BitmapFactory.decodeStream(is2, null, options);
if (bmp != null){
i = 10;
}
else{
System.gc();
SystemClock.sleep(i * 1000);
options.inSampleSize = inSampleSize + 1;
}
} catch (OutOfMemoryError e) {
System.gc();
SystemClock.sleep(i * 1000);
}
}
is2.close();
return bmp;
thanks