Using getPixel and setPixel to convert image into grayscale - java

I am new to programming and I need to know how do I use getpixels to convert the image I have into grayscale.Pls help me: ( I need to get an image from my gallery, convert it into bitmap and start doing image processing. I only have 2 days left for my submission. I really need help with using getPixels.
public class SelectImageActivity extends Activity implements OnClickListener {
// Image loading result to pass to startActivityForResult method.
private static int LOAD_IMAGE_RESULTS = 1;
// GUI components
private Button button; // The button
private ImageView image;// ImageView
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_image);
// Find references to the GUI objects
button = (Button)findViewById(R.id.button);
image = (ImageView)findViewById(R.id.image);
// Set button's onClick listener object.
button.setOnClickListener(this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Here we need to check if the activity that was triggers was the Image Gallery.
// If it is the requestCode will match the LOAD_IMAGE_RESULTS value.
// If the resultCode is RESULT_OK and there is some data we know that an image was picked.
if (requestCode == LOAD_IMAGE_RESULTS && resultCode == RESULT_OK && data != null) {
// Let's read picked image data - its URI
Uri pickedImage = data.getData();
// Let's read picked image path using content resolver
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(pickedImage, filePath, null, null, null);
cursor.moveToFirst();
String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));
Bitmap bitmap1=BitmapFactory.decodeFile(imagePath);
int threshold=50;
int result[];
for (int x=0; x<bitmap1.getWidth();x++)
{
for (int y=0; y<bitmap1.getHeight();y++)
{
if (bitmap1.getPixel(x, y)>threshold)
result[x,y]=255; () //((I have a error here saying "The primitive type int of x does not have a field y"))
else
result[x,y]=0;
}
}

I think the reason for error The primitive type int of x does not have a field y is your result array initialization.
You should wrote :
int[][] result = new int[bitmap1.getWidth()][bitmap1.getHeight()];
instead of int result[]; and access the element using result[x][y].

Related

ImageView not retaining Image when android device restart

I have images selected from the gallery displayed in ImageView, But not retaining or saved Image when the android device restart I need to re-pick an image again. My plan is for the image to still stay on the image view even the device is rebooted , or do I need to create some data to save the image and display to ImageView
public class FirstFragment extends Fragment implements View.OnClickListener{
ImageView imageButton1;
private Uri mImageUri;
#Override
public void onResume() {
super.onResume();
}
private File mSnapFile;
private static final String ARG_URI_IMAGE_1 = "image1Uri";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.fragment_first, container, false);
imageButton1 = (ImageView) v.findViewById(R.id.firstimagebtn);
imageButton1.setOnClickListener(this::onClick);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
String mImageUri = preferences.getString("image", null);
if (mImageUri != null) {
imageButton1.setImageURI(Uri.parse(mImageUri));
}
return v;
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.firstimagebtn:
Intent intent;
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
} else {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
}
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
break;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case 0:
if(resultCode == Activity.RESULT_OK){
if (data != null) {
// This is the key line item, URI specifies the name of the data
mImageUri = data.getData();
// Saves image URI as string to Default Shared Preferences
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("image", String.valueOf(mImageUri));
editor.commit();
// Sets the ImageView with the Image URI
imageButton1.setImageURI(mImageUri);
imageButton1.invalidate();
}
}
break;
case 1:
if(resultCode == Activity.RESULT_OK){
// This is the key line item, URI specifies the name of the data
mImageUri2 = data.getData();
// Saves image URI as string to Default Shared Preferences
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("image2", String.valueOf(mImageUri2));
editor.commit();
// Sets the ImageView with the Image URI
imageButton2.setImageURI(mImageUri2);
imageButton2.invalidate();
}
break;
}
}
You can use image loading libraries like Glide or Picasso. They provide data caching and your image will be persisted.
See docs
By default, Glide checks multiple layers of caches before starting a new request for an image:
1.Active resources - Is this image displayed in another View right now?
2.Memory cache - Was this image recently loaded and still in memory?
3.Resource - Has this image been decoded, transformed, and written to the disk cache before?
4.Data - Was the data this image was obtained from written to the disk cache before?
The first two steps check to see if the resource is in memory and if so, return the image immediately. The second two steps check to see if the image is on disk and return quickly, but asynchronously.
If all four steps fail to find the image, then Glide will go back to the original source to retrieve the data (the original File, Uri, Url etc).
Hope this helps. Let me know if you face an issue with this but I think the docs are pretty much self explanatory.

How to dynamically add items to GridView Android Studio (Java)

Hello I want to have an Add function that allows me to input items to my GridView
For Background: I have a standard GridView and an XML activity (which contains 2 TextView) that I want to convert to my GridView. I also have a custom ArrayAdapter class and custom Word object (takes 2 Strings variables) that helps me do this.
My problem: I want to have an Add button that takes me to another XML-Layout/class and IDEALLY it input a single item and so when the user goes back to MainActivity the GridView would be updated along with the previous information that I currently hard-coded atm. This previous sentence doesn't work currently
Custom ArrayAdapter and 'WordFolder' is my custom String object that has 2 getters
//constructor - it takes the context and the list of words
WordAdapter(Context context, ArrayList<WordFolder> word){
super(context, 0, word);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View listItemView = convertView;
if(listItemView == null){
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.folder_view, parent, false);
}
//Getting the current word
WordFolder currentWord = getItem(position);
//making the 2 text view to match our word_folder.xml
TextView title = (TextView) listItemView.findViewById(R.id.title);
title.setText(currentWord.getTitle());
TextView desc = (TextView) listItemView.findViewById(R.id.desc);
desc.setText(currentWord.getTitleDesc());
return listItemView;
}
}
Here is my NewFolder code. Which sets contentview to a different XML. it's pretty empty since I'm lost on what to do
public class NewFolder extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_folder_view);
Button add = (Button) findViewById(R.id.add);
//If the user clicks the add button - it will save the contents to the Word Class
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//make TextView variables and cast the contents to a string and save it to a String variable
TextView name = (TextView) findViewById(R.id.new_folder);
String title = (String) name.getText();
TextView descText = (TextView) findViewById(R.id.desc);
String desc = (String) descText.getText();
//Save it to the Word class
ArrayList<WordFolder> word = new ArrayList<>();
word.add(new WordFolder(title, desc));
//goes back to the MainActivity
Intent intent = new Intent(NewFolder.this, MainActivity.class);
startActivity(intent);
}
});
}
In my WordFolder class I made some TextView variables and save the strings to my ArrayList<> object but so far it's been useless since it doesn't interact with the previous ArrayList<> in ActivityMain which makes sense because its an entirely new object. I thought about making the ArrayList a global variable which atm it doesn't make sense to me and I'm currently lost.
Sample code would be appreciative but looking for a sense of direction on what to do next. I can provide other code if necessary. Thank you
To pass data between Activities to need to do a few things:
First, when the user presses your "Add" button, you want to start the second activity in a way that allows it to return a result. this means, that instead of using startActivity you need to use startActivityForResult.
This method takes an intent and an int.
Use the same intent you used in startActivity.
The int should be a code that helps you identify where a result came from, when a result comes. For this, define some constant in your ActivityMain class:
private static final int ADD_RESULT_CODE = 123;
Now, your button's click listener should looks something like this:
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent=new Intent(MainActivity.this, NewFolder.class);
startActivityForResult(intent, ADD_RESULT_CODE);
}
});
Now for returning the result.
First, you shouldn't go back to your main activity by starting another intent.
Instead, you should use finish() (which is a method defined in AppCompatActivity, you can use to finish your activity), this will return the user to the last place he was before this activity - ActivityMain.
And to return some data, too, you can use this code:
Intent intent=new Intent();
intent.putExtra("title",title);
intent.putExtra("desc",desc);
setResult(Activity.RESULT_OK, intent);
where title and desc are the variables you want to pass.
in your case it should look something like this:
public class NewFolder extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_folder_view);
Button add = (Button) findViewById(R.id.add);
//If the user clicks the add button - it will save the contents to the Word Class
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//make TextView variables and cast the contents to a string and save it to a String variable
TextView name = (TextView) findViewById(R.id.new_folder);
String title = (String) name.getText();
TextView descText = (TextView) findViewById(R.id.desc);
String desc = (String) descText.getText();
//Save it to the Word class
ArrayList<WordFolder> word = new ArrayList<>();
word.add(new WordFolder(title, desc));
Intent intent=new Intent();
intent.putExtra("title",title);
intent.putExtra("desc",desc);
setResult(Activity.RESULT_OK, intent);
//goes back to the MainActivity
finish();
}
});
}
You should probably also take care of the case where the user changed his mind and wants to cancel adding an item. in this case you should:
setResult(Activity.RESULT_CANCELLED);
finish();
In your ActivityMain you will have the result code, and if its Activity.RESULT_OK you'll know you should add a new item, but if its Activity.RESULT_CANCELLED you'll know that the user changed their mind
Now all that's left is receiving the data in ActivityMain, and doing whatever you want to do with it (like adding it to the grid view).
To do this you need to override a method called onActivityResult inside ActivityMain:
// Call Back method to get the Message form other Activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// check the result code to know where the result came from
//and check that the result code is OK
if(resultCode == Activity.RESULT_OK && requestCode == ADD_RESULT_CODE )
{
String title = data.getStringExtra("title");
String desc = data.getStringExtra("desc");
//... now, do whatever you want with these variables in ActivityMain.
}
}

using getextra to pass xml integer array with an intent to another activity

How would I go about doing this. I was able to pass a xml string array with getExtra but I dont know the syntax to do it for an integer array containg a bunch of #drawable references.
heres how im referencing the string array
//fills route detail image view with xml array of images
final TypedArray image = getResources().obtainTypedArray(R.array.routeImage);
heres how iI have it now with my putExtra using a string array in my mainactivity.java
routeListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String route = values[position];
//for loop to increment through each route list item
int i;
for (i=0; i < values.length;i++)
{
if (route.equals(values[i]))
{
Intent intent = new Intent(view.getContext(), RouteDetails.class);
and heres in
intent.putExtra("route", routeDetail[i]);
startActivity(intent);
}
}
}
}
);
and heres my getExtra in my routeDetail.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_route_details);
//TextView for route details
final TextView routeDetailsView = (TextView) findViewById(R.id.routeDetailsView);
routeDetailsView.setText(getIntent().getExtras().getString("route"));
//ImageView for route details
routeImage = (ImageView) findViewById(R.id.routeImage);
//routeImage.setImageResource(R.drawable.birdsboroareamap);
First store the image Resource in Integer
final TypedArray image = getResources().obtainTypedArray(R.array.routeImage);
int imageId = (int) image.getResourceId(i, -1);
Then add this code right below putting the route Extra
intent.putExtra("imageResourceId", imageId);
Then get the Extra Like this
routeImage.setImageResource(getIntent.getIntExtra("imageResourceId", 0);

android interface callback issue

At the moment I have got 2 class. The main class, and the LinearLayout class that returns linearLayout
The layout class has a button and a edittext view, and its going to bundle all up and return a view back to the main class to use it.
In the main class there will be a ArrayList that will be created here dynamically and in then end, will display them out.
Problem
I want to use QR scanner on each of button. I passed the context to the LinearLayout class in order to create components and create the scanner on the button click. Which it works on click of each created button in the layout list and it automatically callback to the main class onActivityResult method.
But then I want to update the text view for the linearLayout that was clicked.
I don't know how to get the position of which button(linearLayout) was clicked after the callback.
I got a feeling its something to do with Callback / interface. But I don't know how to use it fully
Code of the LinearLayout is call SearchBar :
EditText et;
Button bt;
LinearLayout ll;
IntentIntegrator _scanner;
public SearchBar(Context c){
et=new EditText(c);
bt=new Button(c);
//et.setHint("WayPoint");
bt.setText("Scan");
_scanner = new IntentIntegrator((Activity) c);
ll=new LinearLayout(c);
setLinearLayout();
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
_scanner.initiateScan();
}
});
et.setLayoutParams(flowLeft());
bt.setLayoutParams(flowRight());
ll.addView(et);
ll.addView(bt);
}
public LinearLayout getSearchBar(){
return ll;
}
Code of the main class in brief:
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_search);
//_scanner = new IntentIntegrator(this);
//button_scan = (Button) findViewById(R.id.button_scan);
ScrollView sv = new ScrollView(this);
ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
l2=new LinearLayout(this);
l2.setOrientation(LinearLayout.VERTICAL);
ll.addView(l2);
//testing for searchBar class
SearchBar origin= new SearchBar(this);
origin.setHint("Origin");
origin.setText("me");
sbs.add(origin);
ll.addView(sbs.get(0).getSearchBar());
destin= new SearchBar(this);
destin.setText("destin");
destin.setHint("destination");
destinLayout=destin.getSearchBar();
sbs.add(destin);
ll.addView(destinLayout);
sv.addView(ll);
this.setContentView(sv);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == IntentIntegrator.REQUEST_CODE) { // from Barcode Scanner
if (resultCode == RESULT_OK)
{
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (scanResult == null){
//Alert.ShowAlert(this, "Scanning", "Scan Failed");
}else {
String scanned = scanResult.getContents();
//How to get position of which button was fired
}
}
}
}
The function public void onClick(View v) has the View parameter. You can do whatever you want with that including getId() or getParent(). Maybe you want to call v.getParent() and store that in a class variable so that you can access it in onActivityResult?

using onActivityResult in Fragments

Hi in fragment I want to pick a phone number from contacts and inset it into EditText
but its not working in fragment I use it in activity and it works. Please could you help me how I should change it< thanks
public class Encrypt extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.encrypt, null);
phoneNumberDisplay = (EditText) v.findViewById(R.id.editTextPhoneNumber);
contactsButton=(Button)v.findViewById(R.id.buttonContacts);
contactsButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v==contactsButton){
Intent intent=new Intent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri ur = data.getData();
Cursor c = managedQuery(ur, null, null, null, null);
if (c.moveToFirst()) {
String s = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phoneNumberDisplay.setText(s);
}
}
}
return v;
}
errors: RESULT_OK cannot be resolved to a variable
The method managedQuery(Uri, null, null, null, null) is undefined for the type new
View.OnClickListener(){}
Ok, you have a parenthesis that is not well placed. I suppose you want `onActivityResult to be in the click listener.
contactsButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v==contactsButton){
Intent intent=new Intent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
}
}
});
// ^^
// This parenthesis should not be here
Remove the parenthesis and the semi-colon, and add them here:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri ur = data.getData();
Cursor c = managedQuery(ur, null, null, null, null);
if (c.moveToFirst()) {
String s = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phoneNumberDisplay.setText(s);
}
}
});
// ^^
// Here, so that it is in the event listener
Note: since I fixed the indentation in your post I saw this error. Next time, try to always indent your code correctly, so that you will see that kind of errors (and that's also why I dislike K&R brace style).
Update:
It is Activity.RESULT_OK, not a raw RESULT_OK.
For managedQuery: see this question.
For getContentManager: see here.
For accessing the contacts form your phone, make sure that you added the android.permission.READ_CONTACTS Permission in manifest file..
There could be two possible reasons to this.
Call your statrtActivityForResults using Activity's reference, like
getActivity().startActivityForResult(intent, 1);
Calling super.onActivityResult(requestCode, resultCode, data) in you onActivityResult() as #marcin_j also pointed.
Try either or both of them. See which one works for you.
Here's a link.
You are trying to return value when onActivityResult is void return function, you need to implement your logic without returning any value
public String getPath(Uri uri) {
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Activity ac =new Activity();
Cursor cursor =ac.managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}

Categories

Resources