• Tidak ada hasil yang ditemukan

From the research and studies done, the focus of this experiment is mainly referred to the freshness level of prawn. The experiment also is conducted by using pH paper as the sensoring material. Due different level of pH values for different type of food, this mobile application may not work with other type of food which have different pH range. Hence, it can be recommended that:

1. Continuation of studies by using different type of raw food such as meat, chicken and fish.

2. Changing to different sensoring materials that are more sensitive in changing level of pH of every food or chemicals components.

36

REFERENCES

1. Alasalvar, C., et al., 2010, Seafood Quality, Safety, and Health Applications: An Overview, in Handbook of Seafood Quality, Safety and Health Applications.

Wiley-Blackwell. p. 1-10

2. B Kuswandi, Jayus, A Restyana, A Abdullah, LY Heng, M Ahmad, 2012, A novel colorimetric food package label for fish spoilage based on polyaniline film in Food Control 25(1):18 ·

3. Galagan, Y. and W.F. Su, 2008, Fadable ink for time–temperature control of food freshness: Novel new time–temperature indicator. Food Research International, 41(6): p. 653-6

4. Darlene, 2010, The Danger Zone, Food Safety Matters. Accessed on 27/2/2016 from http://foodsafetymattersyear9.weebly.com/the-danger- zone.html

5. Visiolli, 2009, The Cotemporary Meaning of Food Freshness . dupont packaging resins, DuPont p 1-5

6. B Kuswandi, Jayus, TS Larasati , A Abdullah 2011, Real-Time Monitoring of Shrimp Spoilage Using On-Package Sticker Sensor Based on Natural Dye of Curcumin in Food Analytical Methods 5(4) ·

7. B Kuswandi, R Oktaviana, A Abdullah, LY Heng, 2014 A Novel On-Package Sticker Sensor Based on Methyl Red for Real-Time Monitoring of Broiler Chicken Cut Freshness in Packaging Technology and Science 27(1)

8. B Kuswandi, F Damayanti, Jayus A Abdullah, LY Heng, 2015, Simple and Low- Cost On-Package Sticker Sensor based on Litmus Paper for Real-Time Monitoring of Beef Freshness in Journal of Mathematical and Fundamental Sciences 47(3):236- 251 ·

9. B Kuswandi, Y Wicaksono, A Abdullah, LY Heng, M Ahmad, 2011, Smart Packaging: Sensors for monitoring of food quality and safety in Sensing and Instrumentation for Food Quality and Safety 5(3):137-146 · December 2011 10. K.L. Yam, P.T. Takhistov, J. Miltz, 2005, Intelligent packaging: concepts and

applications. in J. Food Sci. 70(1), R1–R10 (2005)

11. Colour to wavelength relationship. Retrieved on Oct 10, 2016 from https://academo.org/demos/wavelength-to-colour-relationship/

12. B Kuswandi, , D P Kinati, Jayus, A Abdullah, L Y Heng, 2013, Simple &

low-cost freshness indicator for strawberries packaging. Acta Manila.

13. B Kuswandi, , C Maryska, Jayus, A Abdullah, L Y Heng, 2013, Real time on-package freshness indicator for guavas packaging. Journal of Food Measurement and Characterization

14. Statista, 2016b. Worldwide mobile app revenues 2015–2020. Accessed on 4/4/2016 from: http://www.statista.com/statistics/269025/worldwide-mobile-app-revenue forecast

15. R. Garg, R. Telang, 2013, Inferring app demand from publicly available data MIS Q., 37 (4), pp. 1253–1264

37 APPENDICES

Appendix A

package com.mystudio.rgbtest;

import android.Manifest;

import android.content.CursorLoader;

import android.content.DialogInterface;

import android.content.Intent;

import android.database.Cursor;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.provider.MediaStore;

import android.support.v7.app.AlertDialog;

import android.support.v7.app.AppCompatActivity;

import android.view.MotionEvent;

import android.view.View;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.TextView;

import android.widget.Toast;

import com.kimo.lib.alexei.Alexei;

import com.kimo.lib.alexei.Answer;

import com.kimo.lib.alexei.Utils;

import com.kimo.lib.alexei.calculus.DominantColorCalculus;

import com.vistrav.ask.Ask;

import com.vistrav.ask.annotations.AskDenied;

import com.vistrav.ask.annotations.AskGranted;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

//Variables declaration

private ImageView input_imageview;

private TextView rgb_result_textview;

private TextView food_result_textview;

38

private Button more_btn;

private Button camera_btn;

private Button photo_btn;

private Button refresh_btn;

private Button edit_btn;

private View color_indicator_view;

private final int INPUT_IMAGEVIEW_ID = R.id.input_imageview;

private final int RGB_RESULT_TEXTVIEW_ID = R.id.rgb_result_textview;

private final int FOOD_RESULT_TEXTVIEW_ID = R.id.food_result_textview;

private final int MORE_BTN_ID = R.id.more_btn;

private final int CAMERA_BTN_ID = R.id.camera_btn;

private final int PHOTO_BTN_ID = R.id.photo_btn;

private final int REFRESH_BTN_ID = R.id.refresh_btn;

private final int EDIT_BTN_ID = R.id.edit_btn;

private final int COLOR_INDICATOR_VIEW_ID= R.id.color_indicator_view;

private final int CONSTANT_RED = 196;

private final int CONSTANT_GREEN = 159;

private final int CONSTANT_BLUE = 51;

private int REQUEST_CAMERA = 0;

private int SELECT_FILE = 1;

Bitmap bmp;

Uri selectedImageUri = null;

ByteArrayOutputStream stream;

FileOutputStream fo;

boolean isEdit = false;

@Override

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//Call this function to initialize the view of the screen initView();

checkIfImageExist();

//Set on touch listener to the particular button edit_btn.setOnTouchListener(onTouchButtonAnim);

camera_btn.setOnTouchListener(onTouchButtonAnim);

photo_btn.setOnTouchListener(onTouchButtonAnim);

}

@Override

protected void onPause() { super.onPause();

}

@Override

protected void onResume() { super.onResume();

}

@Override

public void onBackPressed() { super.onBackPressed();

}

39

private void initView() {

input_imageview = (ImageView) findViewById(INPUT_IMAGEVIEW_ID);

rgb_result_textview = (TextView) findViewById(RGB_RESULT_TEXTVIEW_ID);

food_result_textview = (TextView) findViewById(FOOD_RESULT_TEXTVIEW_ID);

more_btn = (Button) findViewById(MORE_BTN_ID);

camera_btn = (Button) findViewById(CAMERA_BTN_ID);

photo_btn = (Button) findViewById(PHOTO_BTN_ID);

refresh_btn = (Button) findViewById(REFRESH_BTN_ID);

edit_btn = (Button) findViewById(EDIT_BTN_ID);

color_indicator_view = (View) findViewById(COLOR_INDICATOR_VIEW_ID);

//Set on click listener of particular button more_btn.setOnClickListener(this);

camera_btn.setOnClickListener(this);

photo_btn.setOnClickListener(this);

refresh_btn.setOnClickListener(this);

edit_btn.setOnClickListener(this);

//Make the edit button set to "OFF" by default

edit_btn.setBackgroundResource(R.drawable.btn_orange); //Button orage means 'OFF' button

}

// Change this button responding to onclick private void changeEditBtnBehavior() { //For button UI

if

(edit_btn.getText().equals(getResources().getString(R.string.edit_on))) { edit_btn.setBackgroundResource(R.drawable.btn_orange);

} else { //if the text is 'EDIT OFF'

edit_btn.setBackgroundResource(R.drawable.btn_green);

} }

private void refreshImage() {

if (rgb_result_textview.getText().toString().equals("....")) { //Something here...

} }

//Check if image already exist then execute the function; else display a 'toast' msg

private void checkIfImageExist() {

if (input_imageview.getDrawable() == null) { edit_btn.setEnabled(false);

rgb_result_textview.setText("No image found...");

Toast.makeText(getApplicationContext(), "image not found", Toast.LENGTH_SHORT).show();

} else {

edit_btn.setEnabled(true);

processImageAutoMode();

Toast.makeText(getApplicationContext(), "image found", Toast.LENGTH_SHORT).show();

} }

//Change edit mode

private void changeEditMode() { changeEditBtnBehavior();

String edit_mode = edit_btn.getText().toString();

40

if (edit_mode.equals(getResources().getString(R.string.edit_off))) { //disable edit mode

edit_mode = getResources().getString(R.string.edit_on);

edit_btn.setText(edit_mode);

isEdit = true;

} else if

(edit_mode.equals(getResources().getString(R.string.edit_on))) { edit_mode = getResources().getString(R.string.edit_off);

edit_btn.setText(edit_mode);

isEdit = false;

} else { }

if (isEdit) { //if true

input_imageview.setEnabled(true);

processImageManualMode();

} else {

input_imageview.setEnabled(false);

} }

public static int getHexColor(int[] color) {

return android.graphics.Color.rgb(color[0], color[1], color[2]);

}

//Get RGB value manually

private void processImageManualMode() {

input_imageview.setOnTouchListener(new View.OnTouchListener() { @Override

public boolean onTouch(View view, MotionEvent event) { float eventX = event.getX();

float eventY = event.getY();

float[] eventXY = new float[]{eventX, eventY};

Matrix invertMatrix = new Matrix();

((ImageView) view).getImageMatrix().invert(invertMatrix);

invertMatrix.mapPoints(eventXY);

int x = Integer.valueOf((int) eventXY[0]);

int y = Integer.valueOf((int) eventXY[1]);

System.out.println(

"touched position: "

+ String.valueOf(eventX) + " / "

+ String.valueOf(eventY));

System.out.println(

"touched position: "

+ String.valueOf(x) + " / "

+ String.valueOf(y));

Drawable imgDrawable = ((ImageView) view).getDrawable();

Bitmap bitmap = ((BitmapDrawable) imgDrawable).getBitmap();

System.out.println(

"drawable size: "

+ String.valueOf(bitmap.getWidth()) + " / "

41

+ String.valueOf(bitmap.getHeight()));

//Limit x, y range within bitmap if (x < 0) {

x = 0;

} else if (x > bitmap.getWidth() - 1) { x = bitmap.getWidth() - 1;

}

if (y < 0) { y = 0;

} else if (y > bitmap.getHeight() - 1) { y = bitmap.getHeight() - 1;

}

int touchedRGB = bitmap.getPixel(x, y);

int redValue = Color.red(touchedRGB);

int greenValue = Color.green(touchedRGB);

int blueValue = Color.blue(touchedRGB);

int[] color={redValue,greenValue,blueValue};

color_indicator_view.setBackgroundColor(getHexColor(color));

//color_indicator_view.set(Color.argb(0, redValue, blueValue, greenValue));

rgb_result_textview.setText("R=" + redValue + ", G=" + greenValue + ", B=" + blueValue);

food_result_textview.setText(getResultFromRGB(redValue, greenValue, blueValue));

return true;

} });

}

//Get RGB value automatically by getting the major color private void processImageAutoMode() {

Alexei.with(MainActivity.this) .analyze(input_imageview) .perform(new

DominantColorCalculus(Utils.getBitmapFromImageView(input_imageview))) .showMe(new Answer<Integer>() {

@Override

public void beforeExecution() { //setContentShown(false);

rgb_result_textview.setText("....");

}

@Override

public void afterExecution(Integer answer, long elapsedTime) {

int red = Color.red(answer);

int green = Color.green(answer);

int blue = Color.blue(answer);

int[] color={red,green,blue};

color_indicator_view.setBackgroundColor(getHexColor(color));

rgb_result_textview.setText("R=" + red + ", G=" + green + ", B=" + blue);

42

food_result_textview.setText(getResultFromRGB(red, green, blue));

}

@Override

public void ifFails(Exception error) { }

});

}

//Show a pop up msg to select the image source to pick up private void selectImage() {

final CharSequence[] items = {"Take Photo", "Choose from Gallery", "Cancel"};

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

builder.setTitle("Select item photo");

builder.setItems(items, new DialogInterface.OnClickListener() { @Override

public void onClick(DialogInterface dialog, int item) { if (items[item].equals("Take Photo")) {

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

startActivityForResult(intent, REQUEST_CAMERA);

} else if (items[item].equals("Choose from Gallery")) { Intent intent = new Intent(

Intent.ACTION_PICK,

MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

intent.setType("image/*");

startActivityForResult(

Intent.createChooser(intent, "Select File"), SELECT_FILE);

} else if (items[item].equals("Cancel")) { dialog.dismiss();

} } });

builder.show();

}

//optional : if the camera permission is granted @AskGranted(Manifest.permission.CAMERA)

public void fileAccessGranted() {

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

startActivityForResult(intent, REQUEST_CAMERA);

}

//optional

@AskDenied(Manifest.permission.CAMERA) public void fileAccessDenied() { }

//optional : if the external storage permission is granted @AskGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE) public void mapAccessGranted() {

Intent intent = new Intent(

Intent.ACTION_PICK,

MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

intent.setType("image/*");

43

startActivityForResult(

Intent.createChooser(intent, "Select File"), SELECT_FILE);

}›

//optional

@AskDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE) public void mapAccessDenied() {

}

private void selectCamera(){

Ask.on(this)

.forPermissions(Manifest.permission.CAMERA) .go();

}

private void selectPhoto(){

Ask.on(this)

.forPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE) .go();

}

//Calculation for RGB

public String getResultFromRGB(int r, int g, int b) { String result = "";

double a = 0.00;

double diff_of_red_square = Math.pow(r - CONSTANT_RED, 2);

double diff_of_green_square = Math.pow(g - CONSTANT_GREEN, 2);

double diff_of_blue_square = Math.pow(b - CONSTANT_BLUE, 2);

a = Math.sqrt(diff_of_red_square + diff_of_green_square + diff_of_blue_square);

//Checking for a value if (a >= 65 && a <= 85) {

result = "The food is FRESH ";

} else if (a >= 110 && a <= 135) { result = "The food is GOOD ";

} else if (a >= 140 && a <= 160) { result = "The food is SPOILED ";

} else {

result = "Invalid data";

}

return result;

}

//Navigate to other activity :page private void goToMorePage(){

Intent intent = new Intent();

intent.setClass(MainActivity.this, MoreActivity.class);

startActivity(intent);

}

@Override

public void onClick(View view) { switch (view.getId()) { case MORE_BTN_ID:

goToMorePage();

return;

case CAMERA_BTN_ID:

44

selectCamera();

return;

case PHOTO_BTN_ID:

selectPhoto();

return;

case EDIT_BTN_ID:

changeEditMode();

return;

case REFRESH_BTN_ID:

refreshImage();

return;

default:

} }

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK) {

if (requestCode == REQUEST_CAMERA) {

bmp = (Bitmap) data.getExtras().get("data");

stream = new ByteArrayOutputStream();

bmp.compress(Bitmap.CompressFormat.JPEG, 90, stream);

File destination = new File(

Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");

try {

destination.createNewFile();

fo = new FileOutputStream(destination);

fo.write(stream.toByteArray());

fo.close();

} catch (FileNotFoundException e) { e.printStackTrace();

} catch (IOException e) { e.printStackTrace();

}

input_imageview.setImageBitmap(bmp);

edit_btn.setText(getResources().getString(R.string.edit_on));

edit_btn.setBackgroundResource(R.drawable.btn_orange);

changeEditMode();

checkIfImageExist();

} else if (requestCode == SELECT_FILE) { selectedImageUri = data.getData();

String[] projection = {MediaStore.MediaColumns.DATA};

CursorLoader cursorLoader = new CursorLoader(this, selectedImageUri, projection, null, null, null);

Cursor cursor = cursorLoader.loadInBackground();

int column_index = cursor

.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);

cursor.moveToFirst();

String selectedImagePath = cursor.getString(column_index);

BitmapFactory.Options options = new BitmapFactory.Options();

Dokumen terkait