diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7643783a82f60b3b876fe58a9314fb50520df486
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,123 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <JetCodeStyleSettings>
+      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+    </JetCodeStyleSettings>
+    <codeStyleSettings language="XML">
+      <option name="FORCE_REARRANGE_MODE" value="1" />
+      <indentOptions>
+        <option name="CONTINUATION_INDENT_SIZE" value="4" />
+      </indentOptions>
+      <arrangement>
+        <rules>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:android</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:id</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>style</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>ANDROID_ATTRIBUTE_ORDER</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>.*</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+        </rules>
+      </arrangement>
+    </codeStyleSettings>
+    <codeStyleSettings language="kotlin">
+      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+    </codeStyleSettings>
+  </code_scheme>
+</component>
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000000000000000000000000000000000000..79ee123c2b23e069e35ed634d687e17f731cc702
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/app/src/main/java/itb/bos/bondoman/fragment/ui/twibbon/TwibbonFragment.kt b/app/src/main/java/itb/bos/bondoman/fragment/ui/twibbon/TwibbonFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9a86e5242b02ca759d735b18a9d133831750942e
--- /dev/null
+++ b/app/src/main/java/itb/bos/bondoman/fragment/ui/twibbon/TwibbonFragment.kt
@@ -0,0 +1,298 @@
+package itb.bos.bondoman.fragment.ui.twibbon
+
+import android.content.pm.PackageManager
+import android.content.res.Configuration
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.Canvas
+import android.graphics.Matrix
+import android.os.Bundle
+import android.util.Log
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.Toast
+import androidx.camera.core.Camera
+import androidx.camera.core.CameraSelector
+import androidx.camera.core.ImageCapture
+import androidx.camera.core.ImageCaptureException
+import androidx.camera.core.ImageProxy
+import androidx.camera.core.Preview
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.camera.view.PreviewView
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.google.common.util.concurrent.ListenableFuture
+import itb.bos.bondoman.Manifest
+import itb.bos.bondoman.R
+import itb.bos.bondoman.databinding.FragmentTwibbonBinding
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ * Use the [TwibbonFragment.newInstance] factory method to
+ * create an instance of this fragment.
+ */
+class TwibbonFragment : Fragment() {
+    // TODO: Rename and change types of parameters
+    //izin berkamera
+    private val CAMERA_REQUEST__CODE_PERMISSIONS = 10
+    private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
+
+    private var _binding: FragmentTwibbonBinding? = null
+
+    // This property is only valid between onCreateView and
+    // onDestroyView.
+    private val binding get() = _binding!!
+
+    private lateinit var viewer: PreviewView
+    private lateinit var captureButton: Button
+    private var imageCapture: ImageCapture? = null
+    private lateinit var twibbonViewer: ImageView
+    private var camera: Camera? = null
+    private lateinit var twibbonViewModel:TwibbonViewModel
+    private lateinit var retakePhotoButton: Button
+    private lateinit var switchCameraButton: Button
+    private lateinit var preview: Preview
+    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
+
+    private lateinit var cameraSelector: CameraSelector
+
+    private lateinit var TWIBBON: Bitmap
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+                              savedInstanceState: Bundle?): View? {
+        TWIBBON = BitmapFactory.decodeResource(resources, R.drawable.twibbon)
+        twibbonViewModel =
+                ViewModelProvider(this)[TwibbonViewModel::class.java]
+
+        _binding = FragmentTwibbonBinding.inflate(inflater, container, false)
+        val root: View = binding.root
+        viewer = binding.surfaceView
+        captureButton = binding.twibbonButton
+        twibbonViewer = binding.imageViewer
+        switchCameraButton = binding.flipCameraButton
+        //tambahin listenernya
+        switchCameraButton.setOnClickListener {
+            switchCamera()
+        }
+        retakePhotoButton = binding.retakePhoto
+        //tambahin listenernya
+        retakePhotoButton.setOnClickListener {
+            //tutup viewer sekarang
+            twibbonViewer.visibility = View.GONE
+            //tampilin halaman awal
+            viewer.visibility = View.VISIBLE
+            captureButton.visibility = View.VISIBLE
+            //tutup tombol ini
+            retakePhotoButton.visibility = View.GONE
+            //balikin tombol switch camera
+            switchCameraButton.visibility = View.VISIBLE
+            //hapus twibbon
+            twibbonViewer.setImageBitmap(null)
+        }
+        //tambahin listener
+        captureButton.setOnClickListener {
+            captureImage()
+        }
+        twibbonViewModel.text.observe(viewLifecycleOwner) {
+        }
+        twibbonViewModel._bitmap.observe(viewLifecycleOwner) {
+            //tampilin gambar
+            twibbonViewer.setImageBitmap(twibbonViewModel._bitmap.value)
+            Log.v("IMAGE", twibbonViewModel._bitmap.value.toString())
+        }
+        //tunggu previewview selesai diinit
+        // setting data ulang
+        twibbonViewer.visibility = View.GONE
+        twibbonViewer.setImageBitmap(null)
+        viewer.visibility = View.VISIBLE
+        //cek izin
+        if (!isPermissionGranted()) {
+            ActivityCompat.requestPermissions(
+                    requireActivity(),
+                    REQUIRED_PERMISSIONS, CAMERA_REQUEST__CODE_PERMISSIONS
+            )
+        } else {
+            setupCamera()
+        }
+        return root
+    }
+
+    private fun switchCamera() {
+        cameraSelector = if (cameraSelector == CameraSelector.DEFAULT_BACK_CAMERA) {
+            CameraSelector.DEFAULT_FRONT_CAMERA
+        } else {
+            CameraSelector.DEFAULT_BACK_CAMERA
+        }
+        preview = Preview.Builder().build().also {
+            it.setSurfaceProvider(viewer.surfaceProvider)
+        }
+        imageCapture = ImageCapture.Builder().setTargetRotation(viewer.display.rotation).build()
+        try {
+            camera?.let {
+                preview.setSurfaceProvider(null)
+            }
+            cameraProviderFuture.get().unbindAll()
+            camera?.let {
+                preview.setSurfaceProvider(viewer.surfaceProvider)
+            }
+            camera = cameraProviderFuture.get()
+                    .bindToLifecycle(viewLifecycleOwner, cameraSelector, preview, imageCapture)
+        } catch (e: Error) {
+            Log.e("CAMERA", "Error: $e.localizedMessage")
+        }
+
+    }
+    fun rotateImage(source: Bitmap, angle: Float): Bitmap? {
+        val matrix = Matrix()
+        matrix.postRotate(angle)
+        return Bitmap.createBitmap(
+                source, 0, 0, source.width, source.height,
+                matrix, true
+        )
+    }
+    fun scaleImage(source:Bitmap,scaleX:Float,scaleY:Float):Bitmap?{
+        val matrix = Matrix()
+        matrix.postScale(scaleX,scaleY)
+        return Bitmap.createBitmap(
+                source, 0, 0, source.width, source.height,
+                matrix, true
+        )
+    }
+
+    private fun captureImage() {
+        getBitmapFromImage()
+        viewer.visibility = View.GONE
+        twibbonViewer.setImageBitmap(twibbonViewModel._bitmap.value)
+        twibbonViewer.visibility = View.VISIBLE
+        retakePhotoButton.visibility = View.VISIBLE
+        captureButton.visibility = View.GONE
+        switchCameraButton.visibility = View.GONE
+    }
+
+    private fun getBitmapFromImage() {
+        imageCapture?.takePicture(ContextCompat.getMainExecutor(requireContext()),
+                object : ImageCapture.OnImageCapturedCallback() {
+                    override fun onCaptureSuccess(image: ImageProxy) {
+                        val buffer = image.planes[0].buffer
+                        val bytes = ByteArray(buffer.remaining())
+                        buffer.get(bytes)
+                        val bitmapImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
+                        Log.v("IMAGE", bitmapImage.byteCount.toString())
+                        val orientation = resources.configuration.orientation
+                        var capturedImage:Bitmap? = null
+                        if(cameraSelector==CameraSelector.DEFAULT_BACK_CAMERA){
+                            if(orientation==Configuration.ORIENTATION_PORTRAIT){
+                                capturedImage = rotateImage(bitmapImage, 90.0f)
+                            }
+                            else{
+                                capturedImage = rotateImage(bitmapImage, 180.0f)
+                            }
+                        }
+                        else{
+                            if(orientation==Configuration.ORIENTATION_PORTRAIT){
+                                capturedImage = rotateImage(bitmapImage, 90.0f)
+                                capturedImage = scaleImage(capturedImage!!,-1f,1f)
+                            }
+                            else{
+                                //landscape
+                                capturedImage = rotateImage(bitmapImage, 180.0f)
+                                capturedImage = scaleImage(capturedImage!!,1f,-1f)
+                            }
+                        }
+                        Log.v("TWIBBON", capturedImage.toString())
+                        twibbonViewModel._bitmap.value = applyTwibbon(capturedImage!!)
+                        image.close()
+                    }
+
+                    override fun onError(exception: ImageCaptureException) {
+                        Log.e("IMAGE", "Error capturing image")
+                    }
+                })
+    }
+
+    private fun applyTwibbon(image: Bitmap): Bitmap {
+        val result: Bitmap = Bitmap.createBitmap(image.width, image.height, image.config)
+        val twibbonCanvas = Canvas(result)
+        val Resized_Twibbon = Bitmap.createScaledBitmap(TWIBBON, image.width, image.height, true)
+        twibbonCanvas.drawBitmap(image, 0f, 0f, null)
+        twibbonCanvas.drawBitmap(Resized_Twibbon, 0f, 0f, null)
+        return result
+    }
+
+    private fun setupCamera() {
+        cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
+        cameraProviderFuture.addListener({
+            preview = Preview.Builder().build().also {
+                it.setSurfaceProvider(viewer.surfaceProvider)
+            }
+            imageCapture = ImageCapture.Builder()
+                    .setTargetRotation(viewer.display.rotation)
+                    .build()
+            cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
+            try {
+                camera?.let {
+                    preview.setSurfaceProvider(null)
+                }
+                cameraProviderFuture.get().unbindAll()
+                camera = cameraProviderFuture.get()
+                        .bindToLifecycle(viewLifecycleOwner, cameraSelector, preview, imageCapture)
+            } catch (e: Error) {
+                Log.e("CAMERA", "$e.localizedMessage")
+            }
+        }, ContextCompat.getMainExecutor(requireContext()))
+    }
+
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+
+
+    fun isPermissionGranted() = REQUIRED_PERMISSIONS.all {
+        ContextCompat.checkSelfPermission(requireContext(), it) == PackageManager.PERMISSION_GRANTED
+    }
+
+    override fun onRequestPermissionsResult(
+            requestCode: Int,
+            permissions: Array<out String>,
+            grantResults: IntArray
+    ) {
+        if (requestCode == CAMERA_REQUEST__CODE_PERMISSIONS) {
+            if (isPermissionGranted()) {
+                setupCamera()
+            } else {
+                Toast.makeText(context, "Izin Membuka Kamera Tidak Diberikan!", Toast.LENGTH_SHORT)
+                        .show()
+                requireActivity().finish()
+            }
+        }
+    }
+
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+    }
+
+    override fun onViewStateRestored(savedInstanceState: Bundle?) {
+        super.onViewStateRestored(savedInstanceState)
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+
+    override fun onResume() {
+        super.onResume()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/itb/bos/bondoman/fragment/ui/twibbon/TwibbonViewModel.kt b/app/src/main/java/itb/bos/bondoman/fragment/ui/twibbon/TwibbonViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3b7385b25fa87d3f71e7c4dfed5751f1dce1f045
--- /dev/null
+++ b/app/src/main/java/itb/bos/bondoman/fragment/ui/twibbon/TwibbonViewModel.kt
@@ -0,0 +1,17 @@
+package itb.bos.bondoman.fragment.ui.twibbon
+import android.graphics.Bitmap
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+
+class TwibbonViewModel : ViewModel() {
+
+    private val _text = MutableLiveData<String>().apply {
+        value = "This is twibbon Fragment"
+    }
+    val text: LiveData<String> = _text
+
+    val _bitmap = MutableLiveData<Bitmap?>()
+    private val bitmap: LiveData<Bitmap?>
+        get() = _bitmap
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/twibbon.jpg b/app/src/main/res/drawable/twibbon.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c5481b016535a45f9e1d3083b5fef32d2a14ff9e
Binary files /dev/null and b/app/src/main/res/drawable/twibbon.jpg differ
diff --git a/app/src/main/res/layout/fragment_twibbon.xml b/app/src/main/res/layout/fragment_twibbon.xml
new file mode 100644
index 0000000000000000000000000000000000000000..96502bdddb0b225ac3a87b2b2bd599950ba7075d
--- /dev/null
+++ b/app/src/main/res/layout/fragment_twibbon.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.twibbon.TwibbonFragment">
+
+    <LinearLayout
+        android:id="@+id/imageLayout"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:orientation="vertical"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@+id/buttonLayout">
+        <androidx.camera.view.PreviewView
+            android:id="@+id/surfaceView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            />
+
+        <ImageView
+            android:id="@+id/imageViewer"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone"/>
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/buttonLayout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        app:layout_constraintTop_toBottomOf="@+id/imageLayout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginTop="18dp"
+        android:layout_marginBottom="54dp">
+        <Button
+            android:id="@+id/twibbonButton"
+            android:layout_weight=".5"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="16dp"
+            android:text="@string/twibbonize"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:drawableTint="@color/white"
+            />
+        <Button
+            android:id="@+id/retakePhoto"
+            android:layout_weight=".5"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="16dp"
+            android:text="@string/retake"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:visibility="gone"
+            android:drawableTint="@color/white"
+            />
+
+        <Button
+            android:id="@+id/flipCameraButton"
+            android:layout_weight=".5"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="16dp"
+            android:text="@string/flip_twibbon"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:drawableTint="@color/white"
+            />
+    </LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1a87f450744bfb16b6106255746a5bb1c61eabab..e234b6df57ecab7384baf18fb593d64edf447bda 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -17,5 +17,8 @@
     </string-array>
     <!-- TODO: Remove or change this placeholder text -->
     <string name="hello_blank_fragment">Hello blank fragment</string>
+    <string name="flip_twibbon">Flip Twibbon</string>
+    <string name="twibbonize">Twibbonize</string>
+    <string name="retake">Retake</string>
 </resources>