Xây dựng ứng dụng chụp ảnh và filter camera trên Android (p3)

Hello, hôm nay mình sẽ trình bày nốt về các tính năng cuối cùng trong loạt bài về ứng dụng filter ảnh này. Các tính năng sẽ xây dựng sau khi hoàn thành bài viết:

  • Load ảnh đã chụp từ camera
  • Load ảnh từ bộ nhớ
  • Chỉnh sửa ảnh
  • Cắt ảnh
  • Chia sẻ ảnh

CameraResultActivity

Yeah, ở bài trước, mình đã tạo 1 CameraActivity trống để xử lý các dữ liệu truyền sang từ màn hình chụp ảnh (MainActivity). Sẽ có 2 trường hợp:

  • Xử lý ảnh chụp từ camera

  • Chọn ảnh từ thư viện

Với trường hợp này, ta đơn giản chỉ hiển thị CameraResultActivity và truyền cho nó 1 bundle rỗng. Ok, và nhiệm vụ của ta là sẽ phải xử lý các logic tương ứng với dữ liệu từ MainActivity truyền sang.

Xây dựng layout

Ta sẽ xây dựng layout cho màn hình chỉnh sửa ảnh. Mình tạo 1 file activity_camera_result.xml như sau:

Giao diện này cũng tương tự như giao diện màn hình chụp ảnh (MainActivity), khác mỗi cái là ta thay thế CameraView bằng 1 đối tượng CropImageView. Đây là 1 đối tượng ImageView đặc biệt, cho phép chúng ta lựa chọn vùng ảnh và cắt (crop). Màn hình này cũng chứa 1 list các hiệu ứng cho ta filter lên ImageView. Ok, đơn giản vậy thôi. Hãy tập trung vào việc xây dựng logic!

Xử lý ảnh chụp từ camera

Trước tiên, mình sẽ khai báo 1 biến String để lưu đường dẫn ảnh được truyền sang từ MainActivity (nếu có). 2 biến Bitmap để lưu bitmap của ảnh trước và sau khi filter. Sau đó mình viết 1 hàm get dữ liệu từ MainActivity truyền sang:

Ta đồng thời cũng bind các view từ layout sang activity (sử dụng Butter Knife):

Tiếp theo sẽ gọi hàm getData vừa viết trong hàm onCreate, đồng thời ta sẽ chỉnh sửa lại kích thước các view 1 chút cho đẹp mắt:

Cuối cùng là viết logic xử lý ảnh chụp từ Camera (thực chất là hiển thị file ảnh có đường dẫn lưu trong biến imagePath:

Vậy là khi imagePath có giá trị, ta sẽ hiển thị ảnh lên ivCrop, đồng thời tạo sẵn 1 vùng crop mặc định (là toàn bộ ảnh). Logic này khá đơn giản đúng không.

Xử lý logic chọn ảnh từ thư viện

Trường hợp này được nhận biết bởi việc imagePath không có giá trị (MainActivity truyền 1 bundle rỗng sang). Nên ta sẽ xử lý như sau:

Sau đó, viết lại hàm onActivityResult như thế này:

Trong trường hợp người dùng có chọn ảnh từ thư viện, ta load ảnh đó lên ivvCrop (xử lý tương tự như trường hợp load ảnh chụp từ Camera). Nếu người dùng không chọn ảnh, ta finish activity này liền. Logic cũng khá đơn giản phải không. Ở đây, mình có viết thêm 1 hàm getRealPathFromURI để lấy đường dẫn ảnh mà người dùng chọn:

Vậy là mình đã trình bày xong logic hiển thị ảnh. Giờ sẽ chuyển qua phần xử lý filter cho ảnh.

Chỉnh sửa ảnh

Chức năng này hoàn toàn tương tự như chức năng filter camera mình đã nói ở bài trước. Ta cũng sẽ tạo 1 hàm để hiển thị danh sách các filter lên như sau:

Ta tiếp theo ta sẽ  viết 1 asynctask thực hiện công việc apply filter lên ivCrop:

Cuối cùng, trong hàm setupListFilterEffect, ta thêm đoạn code set sự kiện listener cho item của recycler view:

Vậy là đã hoàn tất việc filter cho ảnh.

Crop ảnh

Giờ ta sẽ làm đến chức năng crop ảnh. Bản thân CropImageView đã cho phép ta chọn vùng ảnh để crop, công việc của ta bây giờ chỉ là xử lý vùng ảnh được chọn đó thôi. Mình sẽ viết hàm xử lý sự kiện xác nhận crop ảnh (khi ấn vào nút continue hoặc done):

Đơn giản là sử dụng hàm startCrop của CropImageView để cắt ảnh, sau đó lưu vào thư mục FeedyPhoto/Filtered. Cuối cùng là truyền đường dẫn ảnh đã lưu sang FinalImageActivity. Đây sẽ là activity có chức năng hiển thị ảnh cuối cùng sau khi chỉnh sửa (filter, crop) và chia sẻ ảnh.

FinalImageActivity

Trước hết mình sẽ tạo 1 activity trống như thế này:

Sau đó khai báo nó trong AndroidManifest.xml

Xây dựng layout

Mình tạo 1 file layout đặt tên là activity_final_image.xml như sau:

Activity này cơ bản là có 1 EditText để viết caption, 1 ImageView để hiển thị ảnh (sau khi chỉnh sửa), và 1 button để chia sẻ ảnh.

Hiển thị ảnh sau khi chỉnh sửa

Đầu tiên mình sẽ khai báo các view sử dụng trong activity trước:

Đơn giản là 1 ImageView và 1 EditText thôi. Thêm vào đó là 1 biến String để chứa đường dẫn ảnh truyền sang từ màn hình CameraResultActivity.

Mình viết 1 hàm getData để lấy dữ liệu truyền sang từ CameraResultActivity:

Hàm này sẽ get được đường dẫn ảnh cần hiển thị. Sau khi lấy được đường dẫn rồi thì hiển thị ra thôi:

Vậy là xong, cùng đi sang chức năng chia sẻ nào.

Chia sẻ ảnh

Mình sẽ bắt sự kiện click cho button có id bt_post:

Tổng kết

Vậy là mình đã trình bày xong toàn bộ các chức năng của app filter ảnh và camera. Toàn bộ source code các bạn lấy tại https://github.com/nanashi1111/ImageFilterDemo. Hãy đọc code và chỉnh sửa cũng như thêm mới các chức năng để hiểu rõ hơn nữa nhé. Nếu có vấn đề gì chưa rõ hãy comment, mình sẽ giải thích.

Hãy chia sẻ

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *