728x90
# 간단한 포토샵 기능
안드로이드 스튜디오에서 구현할 수 있는 이미지 편집 기능 중 7가지를 알아보겠습니다.
# 준비물
- 버튼으로 사용할 이미지 7종
1. 사이즈+, 사이즈-, 밝기+, 밝기-, 그레이스케일, 블러, 엠보싱을 의미하는 32*32 사이즈의 이미지 7장
2. 편집 대상이 될 이미지 1장. 사이즈 300*300 정도 적당한 것. - AndroidManifest.xml
- activity_main.xml
- MainActivity.java
# Android manifest.xml
android:hardwareAccelerated="false"
1. 블러링과 엠보싱 기능을 위해 하드웨어 가속을 꺼줍니다.
AndroidManifest.xml 의 <application "여기에" > </application>에 넣어줍니다.
# activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" // 이미지버튼 부분과 이미지 부분을 세로로 배치
>
<LinearLayout
android:id="@+id/iconLayout"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" // 이미지버튼 레이아웃 1:9 이미지 레이아웃
android:gravity="center">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibZoomin"
android:src="@drawable/icon_sp"/> // 줌인 버튼
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibZoomout"
android:src="@drawable/icon_sm"/> // 줌 아웃 버튼
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibBright"
android:src="@drawable/icon_bp"/> // 밝게 버튼
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibDark"
android:src="@drawable/icon_bm"/> // 어둡게 버튼
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibGray"
android:src="@drawable/icon_g"/> // 회색처리 버튼
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibBlur"
android:src="@drawable/icon_br"/> // 블러링 버튼
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibEmboss"
android:src="@drawable/icon_eb"/> // 엠보싱 버튼
</LinearLayout>
<LinearLayout // 편집될 이미지가 출력될 부분
android:id="@+id/pictureLayout"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="9" // // 이미지버튼 레이아웃 1:9 이미지 레이아웃
android:gravity="center">
</LinearLayout>
</LinearLayout>
메인 화면을 구성하는 소스 코드입니다.
# MainActivity.java
package com.sikuroku.p9_2_photoshop;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.EmbossMaskFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
// 7가지 이미지 버튼 변수
ImageButton ibZoomin, ibZoomout, ibBright, ibDark, ibGray, ibBlur, ibEmboss;
MyGraphicView grapicView; // 사용자 정의한 클래스의 객체
static float scaleX=1, scaleY=1; // 사이즈 변경 관련 변수
static float color = 1; // 밝기 관련 변수
static float satur = 1; // 회색처리 관련 변수
static boolean isBlur = false; // 블러 변수
static boolean isEmboss = false; // 엠보싱 변수
// ### 앱이 생성되면 실행되는 부분 ###
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("미니 포토샵");
LinearLayout pictureLayout = findViewById(R.id.pictureLayout);
grapicView = new MyGraphicView(this);
pictureLayout.addView(grapicView);
clickIcon();
}
// ### 버튼 리스너들을 모아놓은 함수 ###
private void clickIcon(){
// 이미지 버튼 변수에 activiti_main.xml 에서 생성한 이미지버튼의 id를 설정
ibZoomin = findViewById(R.id.ibZoomin);
// 버튼을 누르게 되면
ibZoomin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 버튼에 따라 이미지 조작에 필요한 변수를 조정한 후
scaleX = scaleX + 0.2f;
scaleY = scaleY + 0.2f;
// 현재 출력된 이미지를 무효화하여
// OnDraw 함수로 하여금 재출력하게 한다.
grapicView.invalidate();
}
});
ibZoomout = findViewById(R.id.ibZoomout);
ibZoomout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scaleX = scaleX - 0.2f;
scaleY = scaleY - 0.2f;
grapicView.invalidate();
}
});
ibBright = findViewById(R.id.ibBright);
ibBright.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
color = color + 0.2f;
grapicView.invalidate();
}
});
ibDark = findViewById(R.id.ibDark);
ibDark.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
color = color - 0.2f;
grapicView.invalidate();
}
});
ibGray = findViewById(R.id.ibGray);
ibGray.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(satur==0) satur = 1;
else satur=0;
grapicView.invalidate();
}
});
ibBlur = findViewById(R.id.ibBlur);
ibBlur.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(isBlur) isBlur = false;
else isBlur = true;
grapicView.invalidate();
}
});
ibEmboss = findViewById(R.id.ibEmboss);
ibEmboss.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(isEmboss) isEmboss = false;
else isEmboss = true;
grapicView.invalidate();
}
});
}
// ### 사용자 정의한 클래스 ###
// View 클래스를 상속하였고 레이아웃에 출력할 수 있다.
private static class MyGraphicView extends View{
public MyGraphicView(Context context){
super(context);
}
// 이미지 버튼을 누르면 그 안에 Invalidate()함수가 호출되고
// Invalidate()함수는 현재 보이는 이미지를 무효처리하고
// onDraw() 함수를 재실행하게 합니다.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 사이즈 변경
int cenX = this.getWidth()/2;
int cenY = this.getHeight()/2;
canvas.scale(scaleX, scaleY, cenX, cenY);
// canvas에 그려질 paint를 생성
Paint paint = new Paint();
// 밝기 변경
float[] array = {color, 0,0,0,0,
0,color,0,0,0,
0,0,color,0,0,
0,0,0,1,0};
ColorMatrix cm = new ColorMatrix(array);
// 회색 처리
if(satur==0) cm.setSaturation(satur);
// 밝기변경과 회색처리가 같은 변수 cm을 통하기 때문에
// 회색 처리가 커져있으면 밝기가 적용되지 않습니다.
paint.setColorFilter(new ColorMatrixColorFilter(cm));
// 블러 처리
if(isBlur){
BlurMaskFilter bMask;
bMask = new BlurMaskFilter(30, BlurMaskFilter.Blur.NORMAL);
paint.setMaskFilter(bMask);
}
// 엠보싱 처리
// 엠보싱 코드가 블러 코드보다 아래쪽에 있고
// 같은 paint.setMaskFilter 명령어를 통하기 때문에
// 엠보싱이 켜져있으면 블러 명령어가 무시됩니다.
if(isEmboss){
EmbossMaskFilter eMask;
eMask = new EmbossMaskFilter(new float[] {3,3,3}, 0.5f, 5, 30);
paint.setMaskFilter(eMask);
}
// 편집될 대상이 될 이미지를 불러옵니다.
Bitmap picture = BitmapFactory.decodeResource(getResources(), R.drawable.lovelow);
// 이미지를 중앙에 출력하기 위한 좌표 계산
int picX = (this.getWidth() - picture.getWidth())/2;
int picY = (this.getHeight() - picture.getHeight())/2;
// 크기가 변경된 캔버스에
// 편집될 대상이 될 이미지를
// 캔버스 중앙에
// 요청대로 설정된 paint를 이용해서 출력합니다.
canvas.drawBitmap(picture, picX,picY,paint);
// 캔버스로 이미지를 내보낸 비트맵의 저장공간을 비워줍니다.
picture.recycle();
}
}
}
728x90
'안드로이드' 카테고리의 다른 글
[안드로이드] 간단한 갤러리 앱 만들기 (1) | 2022.12.08 |
---|---|
[안드로이드] 간단한 투표 앱 만들기. intent.putExtra(), getExtra()를 활용. (0) | 2022.12.06 |
[안드로이드] 간단한 터치로 도형그리는 방법 (0) | 2022.11.28 |
[안드로이드] 간단한 Canvas, Paint 클래스 문법 (0) | 2022.11.28 |
[안드로이드] 간단한 이미지뷰어 / SD카드에서 이미지 파일 읽기 (0) | 2022.11.24 |