From d90a878a580c503792c6348539ad95af46f6f575 Mon Sep 17 00:00:00 2001 From: Felix Atsma Date: Mon, 26 Jun 2017 10:43:59 +0200 Subject: [PATCH] Camera filter switching and uploading --- .../tagram/CameraFragment.java | 205 +++++++++++++----- .../myhyvesbookplus/tagram/CameraPreview.java | 7 +- .../tagram/PicturePreview.java | 134 ++++++++++++ .../myhyvesbookplus/tagram/UploadClass.java | 4 +- .../res/drawable/ic_arrow_back_black_24dp.png | Bin 0 -> 199 bytes .../drawable/ic_arrow_forward_black_24dp.png | Bin 0 -> 222 bytes .../src/main/res/layout/fragment_camera.xml | 105 +++++++-- .../app/src/main/res/values/colors.xml | 3 +- .../app/src/main/res/values/ids.xml | 5 + .../app/src/main/res/values/strings.xml | 3 + 10 files changed, 390 insertions(+), 76 deletions(-) create mode 100644 app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/PicturePreview.java create mode 100644 app/MyHyvesBookPlusStagram/app/src/main/res/drawable/ic_arrow_back_black_24dp.png create mode 100644 app/MyHyvesBookPlusStagram/app/src/main/res/drawable/ic_arrow_forward_black_24dp.png create mode 100644 app/MyHyvesBookPlusStagram/app/src/main/res/values/ids.xml diff --git a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraFragment.java b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraFragment.java index b95c281..8ff1e89 100644 --- a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraFragment.java +++ b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraFragment.java @@ -1,25 +1,20 @@ package nl.myhyvesbookplus.tagram; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.net.Uri; import android.os.Bundle; import android.app.Fragment; -import android.support.v7.app.AppCompatActivity; +import android.support.design.widget.FloatingActionButton; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; import android.widget.RelativeLayout; -import android.widget.RelativeLayout.LayoutParams; -import android.widget.Toast; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; /** * A simple {@link Fragment} subclass. @@ -31,6 +26,7 @@ import java.io.IOException; */ public class CameraFragment extends Fragment { // TODO: Rename parameter arguments, choose names that match + private static final String TAG = "CameraFragment"; // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM2 = "param2"; @@ -43,6 +39,9 @@ public class CameraFragment extends Fragment { private Camera mCamera; private CameraPreview mPreview; + private byte[] mPhotoRaw; + private Bitmap mPhoto; + private int facing = Camera.CameraInfo.CAMERA_FACING_BACK; public CameraFragment() { // Required empty public constructor @@ -73,9 +72,6 @@ public class CameraFragment extends Fragment { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } - - // Hide top bar - // ((AppCompatActivity) getActivity()).getSupportActionBar().hide(); } @Override @@ -84,57 +80,130 @@ public class CameraFragment extends Fragment { // Inflate the layout for this fragment final View view = inflater.inflate(R.layout.fragment_camera, container, false); + mCamera = getCameraInstance(facing); + Camera.Parameters params = mCamera.getParameters(); + params.setRotation(0); + mCamera.setParameters(params); + mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera); - final RelativeLayout preview = (RelativeLayout) view.findViewById(R.id.camera_preview); + final RelativeLayout pictureButtons = (RelativeLayout) view.findViewById(R.id.picture_taken_buttons); + final RelativeLayout filterButtons = (RelativeLayout) view.findViewById(R.id.filter_buttons); + final RelativeLayout mCameraLayout = (RelativeLayout) view.findViewById(R.id.camera_preview); +// final RelativeLayout mImageTaken = (RelativeLayout) view.findViewById(R.id.picture_view); - preview.addView(mPreview); + mCameraLayout.addView(mPreview); - // Draw picture and switch button over preview + // Draw buttons over preview view.findViewById(R.id.picture_button).bringToFront(); view.findViewById(R.id.switch_camera_button).bringToFront(); + pictureButtons.bringToFront(); + filterButtons.bringToFront(); - ((ImageButton)view.findViewById(R.id.picture_button)).setOnClickListener(new View.OnClickListener() { + (view.findViewById(R.id.switch_camera_button)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Toast.makeText(getActivity(), "Snap!", Toast.LENGTH_SHORT).show(); - /* - PictureCallback mPicture = new PictureCallback() { + switchFacing(); - @Override - public void onPictureTaken(byte[] data, Camera camera) { - Log.v("picture", "Getting output media file"); - File pictureFile = getOutputMediaFile(); - if (pictureFile == null) { - Log.v("picture", "Error creating output file"); - return; - } - try { - FileOutputStream fos = new FileOutputStream(pictureFile); - fos.write(data); - fos.close(); - } catch (IOException e) { - Log.v("picture", e.getMessage()); - } - } - }; - */ - } - }); - - ((ImageButton)view.findViewById(R.id.switch_camera_button)).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - CameraPreview.switchFacing(); - - preview.removeView(mPreview); + mCameraLayout.removeView(mPreview); + mCamera = getCameraInstance(facing); mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera); - preview.addView(mPreview); + mCameraLayout.addView(mPreview); view.findViewById(R.id.picture_button).bringToFront(); view.findViewById(R.id.switch_camera_button).bringToFront(); } }); + (view.findViewById(R.id.picture_button)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCamera.takePicture(null, null, new PictureCallback() { + @Override + public void onPictureTaken(byte[] data, Camera camera) { + Bitmap bmp = rotate(BitmapFactory.decodeByteArray(data, 0, data.length, null), 90); + mPhoto = bmp; + + PicturePreview mPicPreview = new PicturePreview(getActivity().getBaseContext(), mPhoto); + mPicPreview.setId(R.id.pic_preview); + Log.d(TAG, "onPictureTaken: PICTURE"); + + mCameraLayout.addView(mPicPreview); + + filterButtons.setVisibility(View.VISIBLE); + filterButtons.bringToFront(); + +// mPicPreview.invalidate(); + switchButtons(view); + } + }); + } + }); + + (view.findViewById(R.id.upload_button)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + UploadClass upload = new UploadClass(); + upload.uploadPicture(mPhoto); + + mPhoto.recycle(); + mPhoto = null; + + filterButtons.setVisibility(View.GONE); + switchButtons(view); + + mCameraLayout.removeView(mPreview); + + mCamera = getCameraInstance(facing); + Camera.Parameters params = mCamera.getParameters(); + params.setRotation(0); + mCamera.setParameters(params); + + mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera); + mCameraLayout.addView(mPreview); + + view.findViewById(R.id.picture_button).bringToFront(); + view.findViewById(R.id.switch_camera_button).bringToFront(); + + mCameraLayout.removeView(view.findViewById(R.id.pic_preview)); + } + }); + + (view.findViewById(R.id.filter_left)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCameraLayout.removeView(view.findViewById(R.id.pic_preview)); + + PicturePreview.filterPrev(); + + PicturePreview mPicPreview = new PicturePreview(getActivity().getBaseContext(), mPhoto); + mPicPreview.setId(R.id.pic_preview); + + mCameraLayout.addView(mPicPreview); + + view.findViewById(R.id.picture_taken_buttons).bringToFront(); + filterButtons.setVisibility(View.VISIBLE); + filterButtons.bringToFront(); + } + }); + + (view.findViewById(R.id.filter_right)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCameraLayout.removeView(view.findViewById(R.id.pic_preview)); + + PicturePreview.filterNext(); + + PicturePreview mPicPreview = new PicturePreview(getActivity().getBaseContext(), mPhoto); + mPicPreview.setId(R.id.pic_preview); + + mCameraLayout.addView(mPicPreview); + + view.findViewById(R.id.picture_taken_buttons).bringToFront(); + filterButtons.setVisibility(View.VISIBLE); + filterButtons.bringToFront(); + } + }); + return view; } @@ -162,6 +231,16 @@ public class CameraFragment extends Fragment { mListener = null; } + public static Bitmap rotate(Bitmap bitmap, int degree) { + int w = bitmap.getWidth(); + int h = bitmap.getHeight(); + + Matrix mtx = new Matrix(); + mtx.postRotate(degree); + + return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true); + } + public static Camera getCameraInstance(int facing) { Camera c = null; try { @@ -172,6 +251,34 @@ public class CameraFragment extends Fragment { return c; } + public void switchFacing() { + if (facing == Camera.CameraInfo.CAMERA_FACING_FRONT) + facing = Camera.CameraInfo.CAMERA_FACING_BACK; + else + facing = Camera.CameraInfo.CAMERA_FACING_FRONT; + } + + public void switchButtons(View view) { + RelativeLayout pictureButtons = (RelativeLayout) view.findViewById(R.id.picture_taken_buttons); + FloatingActionButton upload = (FloatingActionButton) view.findViewById(R.id.upload_button); + FloatingActionButton save = (FloatingActionButton) view.findViewById(R.id.save_button); + + if (((Integer)upload.getVisibility()).equals(View.VISIBLE)) { + upload.hide(); + save.hide(); + + view.findViewById(R.id.picture_button).setVisibility(View.VISIBLE); + view.findViewById(R.id.switch_camera_button).setVisibility(View.VISIBLE); + } else { + pictureButtons.bringToFront(); + upload.show(); + save.show(); + + view.findViewById(R.id.picture_button).setVisibility(View.GONE); + view.findViewById(R.id.switch_camera_button).setVisibility(View.GONE); + } + } + @Override public void onPause() { super.onPause(); @@ -182,10 +289,6 @@ public class CameraFragment extends Fragment { super.onResume(); } - public void setCamera(Camera c) { - this.mCamera = c; - } - /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated diff --git a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraPreview.java b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraPreview.java index fb4a199..84fbe45 100644 --- a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraPreview.java +++ b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/CameraPreview.java @@ -8,13 +8,14 @@ import android.view.SurfaceView; import java.io.IOException; public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { + private static String TAG = "CameraPreview"; private SurfaceHolder mHolder; private Camera mCamera; - private static int facing = 0; + private static int facing = Camera.CameraInfo.CAMERA_FACING_BACK; public CameraPreview(Context context, Camera camera) { super(context); - mCamera = camera.open(facing); + mCamera = camera; mCamera.setDisplayOrientation(90); mHolder = getHolder(); @@ -24,6 +25,7 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback @Override public void surfaceCreated(SurfaceHolder mHolder) { try { + Log.d(TAG, "surfaceCreated: CREATED"); mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (IOException e) { @@ -60,6 +62,7 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback @Override public void surfaceDestroyed(SurfaceHolder holder) { + Log.d(TAG, "surfaceDestroyed: DESTROYED"); mCamera.stopPreview(); mCamera.release(); } diff --git a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/PicturePreview.java b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/PicturePreview.java new file mode 100644 index 0000000..4fe18a5 --- /dev/null +++ b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/PicturePreview.java @@ -0,0 +1,134 @@ +package nl.myhyvesbookplus.tagram; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Paint; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * Created by felix on 23/06/2017. + */ + +public class PicturePreview extends SurfaceView implements SurfaceHolder.Callback { + private static final int FILTER_NONE = 0; + private static final int FILTER_SEPIA = 1; + private static final int FILTER_BW = 2; + + private static int currentFilter = FILTER_NONE; + + Bitmap picture; + Bitmap filterPicture; + + public PicturePreview(Context context, Bitmap bmp) { + super(context); + picture = Bitmap.createScaledBitmap(bmp, 1920, 1440, false); + setWillNotDraw(false); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + ColorMatrix cm = new ColorMatrix(); + Paint paint = new Paint(); + ColorMatrixColorFilter filter; + + switch (currentFilter) { + case FILTER_NONE: + canvas.drawBitmap(picture, 0, 0, null); + filterPicture = picture; + break; + case FILTER_SEPIA: + canvas.drawBitmap(toSepia(picture), 0, 0, null); + filterPicture = toSepia(picture); + break; + case FILTER_BW: + cm.setSaturation(0); + filter = new ColorMatrixColorFilter(cm); + paint.setColorFilter(filter); + canvas.drawBitmap(picture, 0, 0, paint); + break; + } + } + + public static void filterPrev() { + switch (currentFilter) { + case FILTER_NONE: + currentFilter = FILTER_BW; + break; + case FILTER_SEPIA: + currentFilter = FILTER_NONE; + break; + case FILTER_BW: + currentFilter = FILTER_SEPIA; + break; + } + } + + public static void filterNext() { + switch (currentFilter) { + case FILTER_NONE: + currentFilter = FILTER_SEPIA; + break; + case FILTER_SEPIA: + currentFilter = FILTER_BW; + break; + case FILTER_BW: + currentFilter = FILTER_NONE; + break; + } + } + + public Bitmap toSepia(Bitmap color) { + int red, green, blue, pixel, gry; + int height = color.getHeight(); + int width = color.getWidth(); + int depth = 20; + + Bitmap sepia = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + + int[] pixels = new int[width * height]; + color.getPixels(pixels, 0, width, 0, 0, width, height); + for (int i = 0; i < pixels.length; i++) { + pixel = pixels[i]; + + red = (pixel >> 16) & 0xFF; + green = (pixel >> 8) & 0xFF; + blue = pixel & 0xFF; + + red = green = blue = (red + green + blue) / 3; + + red += (depth * 2); + green += depth; + + if (red > 255) + red = 255; + if (green > 255) + green = 255; + pixels[i] = (0xFF << 24) | (red << 16) | (green << 8) | blue; + } + sepia.setPixels(pixels, 0, width, 0, 0, width, height); + return sepia; + } + + public Bitmap getPicture() { + return filterPicture; + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + } +} diff --git a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/UploadClass.java b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/UploadClass.java index c3acf21..daf20bb 100644 --- a/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/UploadClass.java +++ b/app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/UploadClass.java @@ -13,6 +13,7 @@ import com.google.firebase.storage.StorageReference; import com.google.firebase.storage.UploadTask; import java.io.ByteArrayOutputStream; +import java.util.Random; /** * Created by marijnjansen on 20/06/2017. @@ -24,7 +25,8 @@ public class UploadClass { public UploadClass() { - mStorageRef = FirebaseStorage.getInstance().getReference().child("images"); + String name = Integer.toString(new Random().nextInt(10000)); + mStorageRef = FirebaseStorage.getInstance().getReference().child("images/" + name); } private byte[] bitmapToBytes(Bitmap bitmap) { diff --git a/app/MyHyvesBookPlusStagram/app/src/main/res/drawable/ic_arrow_back_black_24dp.png b/app/MyHyvesBookPlusStagram/app/src/main/res/drawable/ic_arrow_back_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..7726760865bee01ff1f2b06fb58cbab901d0b6e4 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcg`aE46Ln;{G-f|aZHWWCPz|7%k zY`FdD)1ukGm;I}p-`23jG*#*zNJB%RT2%d9$(z46axRVM-1uv%z>4_Go4>CAw!nYB zUG1+gFE1~LGVJ;P`upzs=XE{)J<|`Cnz{Jv2Y5hc)%DX+0(`1=f~S_ j`;+@u4rsxF`x_XKKUCeUxL{cZkjvod>gTe~DWM4fCOJ*w literal 0 HcmV?d00001 diff --git a/app/MyHyvesBookPlusStagram/app/src/main/res/drawable/ic_arrow_forward_black_24dp.png b/app/MyHyvesBookPlusStagram/app/src/main/res/drawable/ic_arrow_forward_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5a68183db0af5ae96767121f57a6a5f4290587 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgmU_B4hEy=Vz2(SvFhHdB;daKH zNwqO=cz5sOQOQqHa4mlH`yJc4`6h3dFf%Yb@P1Wzuy3*ZbG12c_Un_L1L@~Kj znKyHTq&TOLipK;6$0imSqouWK>FO^H{i-EZPRrFeK5$IE{(?Wpc>mF7v-AI5{qucB z{=T2j?*A(SlJC!$->>-`zQKR4edwz{D}$c - + android:layout_height="match_parent" > + + + + + + + android:id="@+id/filter_buttons" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" + android:layout_marginBottom="60dp" + android:layout_centerVertical="true"> + + + + + + + + android:layout_alignParentLeft="true" + android:scaleType="center" + app:fabSize="normal" + android:src="@android:drawable/ic_menu_upload"/> - - + android:layout_alignParentBottom="true" + android:scaleType="center" + app:fabSize="normal" + android:src="@android:drawable/ic_menu_save"/> - + diff --git a/app/MyHyvesBookPlusStagram/app/src/main/res/values/colors.xml b/app/MyHyvesBookPlusStagram/app/src/main/res/values/colors.xml index a27903e..9709ac7 100644 --- a/app/MyHyvesBookPlusStagram/app/src/main/res/values/colors.xml +++ b/app/MyHyvesBookPlusStagram/app/src/main/res/values/colors.xml @@ -2,5 +2,6 @@ #fbbf2d #ffa70f - #4CAF50 + #4bAfe5 + diff --git a/app/MyHyvesBookPlusStagram/app/src/main/res/values/ids.xml b/app/MyHyvesBookPlusStagram/app/src/main/res/values/ids.xml new file mode 100644 index 0000000..0754da4 --- /dev/null +++ b/app/MyHyvesBookPlusStagram/app/src/main/res/values/ids.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml b/app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml index a5f3ee1..4b3b06d 100644 --- a/app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml +++ b/app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml @@ -24,4 +24,7 @@ profile picture Change Password Please Wait + + Upload + Save