I have an activity which contains a gridview which is used to display the images by camera or gallery, however I found that it may cause OutOfMemory exception sometimes, this is the code codes, I am not sure what's the problem?
public class WaterPointSubmitActivity extends Activity {
private final int DIALOG_TYPE_IMAGE = 11;
private final int Result_Code_Camera = 11;
private final int Result_Code_Local = 12;
private final int Dialog_Source_Value_TakePhoto = 0; // the index in the array.xml
private final int Dialog_Source_value_Local = 1;
private ArrayList<String> mGridViewImages = new ArrayList<String>();
private GridView mGridView;
private ImageAdapter mGridViewAdapter;
private ImageView mImageAddButton;
private Uri mPhotoToBeUploadURI;
private AsyncHttpClient mAsyncHttpClient = Helper.getAsyncHttpClient();
private RequestHandle mCurrentRequset;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_point_submit);
this.setupViews();
}
private void setupViews() {
mGridView = (GridView) findViewById(R.id.images_grid_view);
mGridViewAdapter = new ImageAdapter(this, R.layout.common_expose_image_item, mGridViewImages);
mGridView.setAdapter(mGridViewAdapter);
//trigger the image choose dialog
mImageAddButton = (ImageView) findViewById(R.id.pollution_add_image);
mImageAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDialog(DIALOG_TYPE_IMAGE);
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
switch (id) {
case DIALOG_TYPE_IMAGE:
builder.setTitle(getString(R.string.dialog_choose_photo)).setItems(R.array.point_image_source, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case Dialog_Source_Value_TakePhoto:
//get image by camera
mPhotoToBeUploadURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoToBeUploadURI);
startActivityForResult(cameraIntent, Result_Code_Camera);
break;
case Dialog_Source_value_Local:
//from gallery
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, Result_Code_Local);
break;
}
}
});
Dialog target = builder.create();
target.setCanceledOnTouchOutside(false);
return target;
}
return null;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
if (resultCode == RESULT_OK) {
String imageFile = null;
switch (requestCode) {
case Result_Code_Camera:
String[] projection = {
MediaStore.MediaColumns._ID,
MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.Images.Media.DATA
};
Cursor c = getContentResolver().query(mPhotoToBeUploadURI, projection, null, null, null);
c.moveToFirst();
imageFile = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
break;
case Result_Code_Local:
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageFile = cursor.getString(columnIndex);
cursor.close();
break;
}
mGridViewImages.add(imageFile);
mGridViewAdapter.notifyDataSetChanged();
}
}
class ImageAdapter extends ArrayAdapter<String> {
private int mResourceId;
public ImageAdapter(Context context, int resource, List<String> items) {
super(context, resource, items);
mResourceId = resource;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null || convertView.getTag() == null) {
convertView = getLayoutInflater().inflate(mResourceId, parent, false);
holder = new ViewHolder();
holder.pointImage = (ImageView) convertView.findViewById(R.id.pollution_image);
holder.pointDeleteImage = convertView.findViewById(R.id.pollution_image_delete);
convertView.setTag(holder);
holder.pointDeleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
deleteImage(position);
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
String filePath = getItem(position);
if (filePath != null) {
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
holder.pointImage.setImageBitmap(bitmap);
}
return convertView;
}
}
private void deleteImage(int position) {
mGridViewImages.remove(position);
mGridViewAdapter.notifyDataSetChanged();
}
static class ViewHolder {
ImageView pointImage;
View pointDeleteImage;
}
}
What's the problem?
your view is loading full sized bitmaps causing OOM use BitmapFactory options to scale the bitmap before it is loaded into memory
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedImagePath, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
options.inSampleSize = calculateInSampleSize(options,320,480);
options.inJustDecodeBounds = false;
Bitmap photo = BitmapFactory.decodeFile(selectedImagePath,options);
Helper Method
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) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
You just need to add this line to your manifest file....It will allocate the large memory for your application..
android:largeHeap="true"
Related
So we're trying to implement an upload image feature in our Android App.
In our registration page, there is an upload button and once pressed, it should redirect to the image gallery and once an image is selected, it should be displayed in the ImageView placed.
Here's an excerpt of the code we're trying to work on.
The issue is, for some images it is correctly displayed but for some, it is either rotated 90 degrees to the right or 180 degrees.
What could be the issue?
public class Register extends AppCompatActivity {
private String mName = "";
private String mUsername = "";
private String mPassword = "";
private String mCompany = "";
private String mContact = "";
private static final int PICK_IMAGE = 100;
ImageView imageView;
Uri imageUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Intent recvdIntent = getIntent();
mName = recvdIntent.getStringExtra("NAME");
mUsername = recvdIntent.getStringExtra("USERNAME");
mPassword = recvdIntent.getStringExtra("PASSWORD");
mCompany = recvdIntent.getStringExtra("COMPANY");
mContact = recvdIntent.getStringExtra("CONTACT");
imageView = (ImageView)findViewById(R.id.imageView);
Button btnSubmit = (Button) findViewById(R.id.btn_register);
btnSubmit.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
submitUserData();
Intent launchIntent = new Intent(Register.this, Category.class);
return;
}
}
);
Button upload = (Button) findViewById(R.id.btn_upload);
upload.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
openGallery();
}
});
return;
}
private void openGallery() {
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, PICK_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) {
imageUri = data.getData();
imageView.setImageURI(imageUri);
}
}
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
ExifInterface ei = new ExifInterface(image_absolute_path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotate(bitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotate(bitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotate(bitmap, 270);
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
return flip(bitmap, true, false);
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
return flip(bitmap, false, true);
default:
return bitmap;
}
}
public static Bitmap rotate(Bitmap bitmap, float degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
Matrix matrix = new Matrix();
matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
private void submitUserData() {
EditText edtName = (EditText) findViewById(R.id.edt_name);
EditText edtCompany = (EditText) findViewById(R.id.edt_company);
EditText edtContact = (EditText) findViewById(R.id.edt_contact);
EditText edtUsername = (EditText) findViewById(R.id.edt_username);
EditText edtPassword = (EditText) findViewById(R.id.edt_password);
TaraApp2 app = (TaraApp2) getApplication();
app.saveUserData(edtName.getText().toString(),edtUsername.getText().toString(),
edtPassword.getText().toString(),
edtCompany.getText().toString(),
edtContact.getText().toString() );
finish();
return;
}
}
Uri selectedImageUri = data.getData();
Bitmap bitmap = scaleImage(this,selectedImageUri);
public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}
String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
for getting url of the image use this
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
For accessing picture from your gallery you can use the croperino library.
https://android-arsenal.com/details/1/4374
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Croperino.prepareGallery(MainActivity.this);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CroperinoConfig.REQUEST_PICK_FILE:
if (resultCode == Activity.RESULT_OK) {
CroperinoFileUtil.newGalleryFile(data, MainActivity.this);
Croperino.runCropImage(CroperinoFileUtil.getmFileTemp(),
MainActivity.this, true, 1, 1, 0, 0);
}
break;
case CroperinoConfig.REQUEST_CROP_PHOTO:
if (resultCode == Activity.RESULT_OK) {
Uri i = Uri.fromFile(CroperinoFileUtil.getmFileTemp());
ivMain.setImageURI(i);
//Do saving / uploading of photo method here.
//The image file can always be retrieved via
CroperinoFileUtil.getmFileTemp()
}
break;
default:
break;
}
}
so i am trying now for about a week to get this thing working but to no avail....
i want the user to pick an image from his gallery and then crop that image into a nice circle profile photo i get the photo to crop but the background is still square.... i found this question and tried implementing the answer he gave but still the background is square Cropping circular area from bitmap in Android
i googled and just found more ways to do it but still gets the square background.... any help will be appreciated
public class RegisterActivity extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
RoundedImageView roundImageView ;
String numberToPass = "1";//default 1 for male
String selectedImagePath;
EditText etNickname, etAge;
Button btnNext;
ImageView profilePhoto, imageview;
Bitmap bitmap;
private OnRegisterListener mListener;
public RegisterActivity() {
// Required empty public constructor
}
public static RegisterActivity newInstance(String param1, String param2) {
RegisterActivity fragment = new RegisterActivity();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register, container, false);
etNickname = (EditText) view.findViewById(R.id.etNickName);
btnNext = (Button) view.findViewById(R.id.btnNextRegister);
profilePhoto = (ImageView) view.findViewById(R.id.imageButton);
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.blender);
// profilePhoto.setImageBitmap(bitmap);
/* Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(),R.drawable.blender);
Bitmap circularBitmap = ImageConverter.getRoundedCornerBitmap(bitmap2, 100);
ImageView circularImageView = (ImageView)view.findViewById(R.id.imageButton);
circularImageView.setImageBitmap(circularBitmap); */
profilePhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openGallery();
}
});
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnRegisterListener) {
mListener = (OnRegisterListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnRegisterListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnRegisterListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
//this allows the uset to select one image from openGallery
public void openGallery() {
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, 1);
}
//when starting activity for result and choose an image, the code will automatically continue here
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == 1 && null != data) {
if (requestCode == 1) {
Uri current_ImageURI = data.getData();
/* String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(current_ImageURI,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();*/
selectedImagePath = getPath(current_ImageURI);
profilePhoto.setImageBitmap(circleBitmap(decodeSampledBitmap(new File(selectedImagePath), 250, 250)));
}
}
}
public String getPath(Uri contentUri) {
// we have to check for sdk version because from lollipop the retrieval of path is different
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// can post image
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else {
String filePath = "";
String wholeID = DocumentsContract.getDocumentId(contentUri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
}
public Bitmap decodeSampledBitmap(File res, int reqWidth, int reqHeight) {
if (res != null) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
FileInputStream stream2 = null;
try {
stream2 = new FileInputStream(res);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BitmapFactory.decodeStream(stream2, null, options);
stream2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Calculate inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
o2.inJustDecodeBounds = false;
FileInputStream stream = null;
try {
stream = new FileInputStream(res);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, o2);
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
} else
return null;
}
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;
}
//-----------------------------------------------------------------
private Bitmap circleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
int squareBitmapWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
/* Canvas
The Canvas class holds the "draw" calls. To draw something, you need 4 basic
components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing
into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint
(to describe the colors and styles for the drawing). */
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
// final Rect rect = new Rect(0, 0, squareBitmapWidth, squareBitmapWidth);
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
//canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//float left = (squareBitmapWidth - bitmap.getWidth()) / 2;
//float top = (squareBitmapWidth - bitmap.getHeight()) / 2;
//canvas.drawBitmap(bitmap, left, top, paint);
canvas.drawBitmap(bitmap, rect, rect, paint);
//bitmap.recycle();
return output;
}
//---------------------------------------------------------------------------------------------
//end img upload
I use this code and it works perfectly:
public static Bitmap getCircularBitmap(Bitmap bitmap) {
Bitmap output;
if (bitmap.getWidth() > bitmap.getHeight()) {
output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
} else {
output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
float r = 0;
if (bitmap.getWidth() > bitmap.getHeight()) {
r = bitmap.getHeight() / 2;
} else {
r = bitmap.getWidth() / 2;
}
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(r, r, r, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
You can custom ImageView to make its all drawing things circular. Here is my implementation(not the best solution for performance-eager application but good enough for condition that don't invalidate ImageView much):
class CircleImageView extends ImageView {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public CircleImageView(Context context) {
super(context);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int radiusMeasureSpec = widthMeasureSpec;
super.onMeasure(radiusMeasureSpec, radiusMeasureSpec);
int radiusMeasureSize = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(radiusMeasureSize, radiusMeasureSize);
}
#Override
public void draw(Canvas viewCanvas) {
final int EDGE_SIZE = viewCanvas.getWidth();
// Draw this View's things.
Bitmap fgBm = Bitmap.createBitmap(EDGE_SIZE, EDGE_SIZE, Bitmap.Config.ARGB_8888);
Canvas fgCanvas = new Canvas(fgBm);
super.draw(fgCanvas);
// Transfer to a special shape.
Bitmap shapedBm = Bitmap.createBitmap(EDGE_SIZE, EDGE_SIZE, Bitmap.Config.ARGB_8888);
Canvas shapedCanvas = new Canvas(shapedBm);
shapedCanvas.drawCircle(EDGE_SIZE/2, EDGE_SIZE/2, EDGE_SIZE/2, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
shapedCanvas.drawBitmap(fgBm, 0, 0, mPaint);
mPaint.setXfermode(null);
// Move drawn things to View's canvas.
viewCanvas.drawBitmap(shapedBm, 0, 0, mPaint);
fgBm.recycle();
shapedBm.recycle();
}
}
There's someone who customizes ImageView using BitmapShader in an SO post without Xfermode and create extra Bitmap instances. Here's his implementation.
you can use trusted library like This one
Adding circle image adding border to your image and some other feature
I have FirstscreenActivity, in which I use RecyclerView, (in this RecyclerView displays pictures of the projects which were created by a user), then user goes to the next Activity, where he creates new project and adds pictures there. When user comes back to the FirstScreenActivity, old project downloads one more time, and after that download new project.
How to make that old projects wouldn't download one more time after the changing the Activities (so there wouldn't be duplicates)?
public class FirstscreenActivity extends AppCompatActivity implements RecyclerItemClickListener.OnItemClickListener {
private MyAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
public static String mCurrentProject = null;
RecyclerView list;
static File[] listFile;
static File[] listFolders;
static int newpressed = 0;
public static ArrayList<Folder> FOLDERS = new ArrayList<>();
public static LruCache<String, Bitmap> mMemoryCache;
public static File[] listFile2;
public void getFromSdcardFolders() {
File file = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture", "Previews");
if (file.isDirectory()) {
listFolders = file.listFiles();
for (int i = 0; i < listFolders.length; i++) {
Folder folderobject = new Folder();
folderobject.setName(listFolders[i].getName());
Log.i("List of FOLDERS: ", String.valueOf(listFolders[i].getName()));
File picturelist = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture/Previews", listFolders[i].getName());
if (picturelist.isDirectory()) {
listFile = picturelist.listFiles();
for (int j = 0; j < listFile.length; j++) {
folderobject.addFile(listFile[j].getAbsolutePath());
}
}
FOLDERS.add(folderobject);
Log.wtf("TAG", "Folders size inside the getFRom:" + FOLDERS.size());
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.front);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setTitle("");
list = (RecyclerView) findViewById(R.id.list);
list.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getApplicationContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
list.addOnItemTouchListener(new RecyclerItemClickListener(this, this));
getFromSdcardFolders();
list.setLayoutManager(mLayoutManager);
mAdapter = new MyAdapter(this, FOLDERS);
list.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 4;
mMemoryCache
= new LruCache<String, Bitmap>(cacheSize) {
#Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addItem:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss");
Date now = new Date();
mCurrentProject = String.valueOf(formatter.format(now));
Log.d("newpressed: ", String.valueOf(newpressed));
Intent nextScreen = new Intent(getApplicationContext(), AudioRecord.class);
startActivity(nextScreen);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onItemClick(View childView, int position) {
File picturelist2 = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture/Pictures", listFolders[position].getName());
if (picturelist2.isDirectory()) {
listFile2 = picturelist2.listFiles();
for (int i = 0; i < listFile2.length; i++) {
Log.i("LIST OF PICTURES: ", String.valueOf(listFile2[i]));
}
}
Intent viewScreen = new Intent(getApplicationContext(), ViewActivity.class);
viewScreen.putExtra("FILE_TAG", listFile2);
startActivity(viewScreen);
}
#Override
public void onItemLongPress(View childView, int position) {
}
}
Code of the adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>` {
public final Activity context;
public final ArrayList<Folder> FOLDERS;
View view;
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
Log.wtf("TAG", "Folders size: " + FOLDERS.size());
return FOLDERS.size();
}
// optimisation of bitmap
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;
}
public static Bitmap decodeSampledBitmapFromResource(String path,
int reqWidth, int reqHeight) {
// 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;
return BitmapFactory.decodeFile(path, options);
}
public void loadBitmap(String path, ImageView imageView, int position) {
final String imageKey = String.valueOf(path);
Bitmap bitmap = getBitmapFromMemCache(imageKey);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
bitmap = decodeSampledBitmapFromResource(path, 100, 100);
imageView.setImageBitmap(bitmap);
// BitmapWorkerTask task = new BitmapWorkerTask(imageView, position);
// task.execute(path);
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public TextView title;
public ImageView image1;
ImageView image2;
ImageView image3;
ImageView image4;
ImageView image5;
TextView slides;
public ViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.item);
image1 = (ImageView) v.findViewById(R.id.icon1);
image2 = (ImageView) v.findViewById(R.id.icon2);
image3 = (ImageView) v.findViewById(R.id.icon3);
image4 = (ImageView) v.findViewById(R.id.icon4);
image5 = (ImageView) v.findViewById(R.id.icon5);
slides = (TextView) v.findViewById(R.id.textView1);
}
}
public MyAdapter(Activity context, ArrayList<Folder> FOLDERS) {
this.context = context;
this.FOLDERS = FOLDERS;
getItemCount();
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Log.wtf("TAG", "OnCreateViewHolder works!!!");
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.mylist, parent, false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Folder folder = FOLDERS.get(position);
holder.image1.setImageResource(R.drawable.placeholder);
holder.image2.setImageResource(R.drawable.placeholder);
holder.image3.setImageResource(R.drawable.placeholder);
holder.image4.setImageResource(R.drawable.placeholder);
holder.image5.setImageResource(R.drawable.placeholder);
ArrayList<String> imgs = folder.getPicturelist();
holder.title.setText(folder.getName());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 10;
for (int i = 0; i < 5; i++) {
switch (i) {
case 0:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image1, position);
} else {
holder.image1.setImageBitmap(null);
// holder.image1.setImageResource(R.drawable.placeholder);
}
break;
case 1:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image2, position);
} else {
holder.image2.setImageBitmap(null);
// holder.image2.setImageResource(R.drawable.placeholder);
}
break;
case 2:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image3, position);
} else {
holder.image3.setImageBitmap(null);
// holder.image3.setImageResource(R.drawable.placeholder);
}
break;
case 3:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image4, position);
} else {
holder.image4.setImageBitmap(null);
// holder.image4.setImageResource(R.drawable.placeholder);
}
break;
case 4:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image5, position);
} else {
holder.image5.setImageBitmap(null);
// holder.image5.setImageResource(R.drawable.placeholder);
}
break;
}
}
holder.slides.setText("Количество слайдов: " + imgs.size());
view.setTag(holder);
}
public Bitmap getBitmapFromMemCache(String key) {
return com.example.attracti.audiorecorderpicture.FirstscreenActivity.mMemoryCache.get(key);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myproject">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"
android:name=".model.App"
>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<activity android:name=".activities.AudioRecord"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity android:name=".activities.FirstscreenActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activities.ViewActivity">
</activity>
</application>
</manifest>
Solution
If you are going back to first activity with intent, it will create the activity again, as expected. To prevent this, you can add this to manifest:
<activity android:name=".activities.FirstscreenActivity"
android:launchMode= "singleInstance"
...
singleInstance will create activity only once.
Solution
Use finish() when you want to go back.
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]);
In this piece of my code i want to change the image when i click on it. How i can do this?
I use img.setOnClickListenser but really i don't know what the code must put in it
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.gallery_img2, container, false);
Log.d("start_new_frg gallery_img ", "ok");
back = (Button)rootView.findViewById(R.id.button1);
if (id == -1 ){
Toast.makeText(getActivity(), "bad Entry ", Toast.LENGTH_LONG).show();
onBackPressed();
getActivity().finish();
}
imgv = (ImageView) rootView.findViewById(R.id.imageView1);
String ROOT = Environment.getExternalStorageDirectory().getPath()+"/POSTSIMAGES/";
final Bitmap image = BitmapFactory.decodeFile(ROOT+String.valueOf(g.getId())+"q.jpg");
File f = new File(ROOT+String.valueOf(g.getId())+"q.jpg");
temp=ROOT;
if(!f.exists()){
imgv.setImageResource(R.drawable.logo_and);
}
else
{
imgv.setImageBitmap(image);
}
if( isNetworkConnected( )){
new conn().execute("");
}else{
// pd.dismiss();
// if(ROOT.endsWith("_s"))
// {
//
//
// }
imgv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// your code here
Log.d("inside onclick", "ok");
String _n=temp.replace("_s.jpg", "_n.jpg");
imageLoader2.DisplayImage(_n,imgv );
// imgv.setScaleType(ImageView.ScaleType.FIT_XY);
}
});
}
//////////////////////// ADS ///////////////////////
// Create the adView
adView = new AdView(getActivity(), AdSize.SMART_BANNER, "a150f45ea765784");
// Lookup your LinearLayout assuming it's been given
// the attribute android:id="#+id/mainLayout"
LinearLayout layout = (LinearLayout)rootView.findViewById(R.id.ADS);
// Add the adView to it
layout.addView(adView);
// Initiate a generic request to load it with an ad
adView.loadAd(new AdRequest());
//////////////////////// END ADS ///////////////////////
back.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Fragment newFragment = new Gallery(getActivity());
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(android.R.id.content, newFragment);
// transaction.addToBackStack(null);
// Commit the transaction
// transaction.remove(mFragment);
transaction.commit();
}
});
return rootView;
}
Use same code to create another bitmap of the image you want and assign it to your Imageview.
imgv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// your code here
final Bitmap new_image = BitmapFactory.decodeFile(ROOT+String.valueOf(g.getId())+"q.jpg");
imgv.setImageBitmap(new_image);
}
});
Try this one
final Bitmap image = BitmapFactory.decodeFile(ROOT+String.valueOf(g.getId())+"q.jpg");
Bitmap bitmapimage = Bitmap.createScaledBitmap(image, 60, 60, true);
or you can call this method pass path of the image and size of width and height like 60 and 60
public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
return bmp;
}
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) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}