반응형
파이썬으로 투명 배경의 이미지로 만드는 방법

아래 코드에서 pixel 배열에 R,G,B 값이 들어있으므로 원하는 컬러를 투명하게 처리할 수 있다.

색깔 범위를 +- 5~10정도 주면 좀 더 배경을 잘 제거 할 수 도 있을 것이다. 

from PIL import Image

# 이미지 파일 열기
image = Image.open("image.png")

# 새로운 alpha channel 생성
alpha_data = []
for pixel in image.getdata():
    if pixel[0] == 255 \
        and pixel[1] == 255 \
        and pixel[2] == 255:
        alpha_data.append(0)
    else:  # 그 외의 경우 alpha 값을 255로 설정
        alpha_data.append(255)
alpha_channel = Image.new("L", image.size)
alpha_channel.putdata(alpha_data)

# alpha channel을 이용하여 이미지의 배경을 투명하게 만듦
new_image = image.convert("RGBA")
new_image.putalpha(alpha_channel)

# 이미지 파일 저장
new_image.save("transparent_image.png")

색상 범위를 쉽게 주려면?  아래 코드 참고

# 색상 범위 설정
lower_color = (245, 245, 245)  # 검색할 색상 범위의 최소값
upper_color = (255, 255, 255)  # 검색할 색상 범위의 최대값


    if lower_color <= pixel <= upper_color:
        alpha_data.append(0)
    else:  # 그 외의 경우 alpha 값을 255로 설정
        alpha_data.append(255)

'Python' 카테고리의 다른 글

Drawing Plot, 투명 이미지 datauri 생성  (0) 2023.03.20
set에 set 추가? frozenset  (0) 2021.02.24
Jupyter Notebook 소스 복구  (0) 2020.06.16
Docker python venv 패키지 유지  (0) 2020.06.07
딕셔너리에서 키삭제  (0) 2019.12.07
반응형
포인트 리스트를 가지고 그림을 드로잉하고, 이것을 원하는 크기로 Resize 하고, 투명 이미지 datauri 만들기...
pointlist = '[(10,10)(20,20)(40,50)(60,80)][(10,80)(24,70)(40,60)(60,40)]'

# image 필드에 데이터가 없는 목록만 뽑아서 배치 작업을 수행한다.
def to_datauri(sn):
    sn = sn.strip()
    # 정규표현식으로 포맷 문자열에서 점 정보 추출
    point_regex = r"\(([-+]?\d+),([-+]?\d+)\)"
    strokes = sn.replace('[', '')
    strokes = strokes.split(']')
    strokes = [ s for s in strokes if s!='' ]

    # 그래프 그리기
    plt.figure()
    fig, ax = plt.subplots(figsize=(3, 2))
    ax.set_facecolor('none') # 배경 투명
    fig.patch.set_alpha(0) # 배경 투명
    # 축과 눈금 숨기기
    ax.axis('off')

    # 각 획별로 분리하여 그리기
    for stroke in strokes:
        points = re.findall(point_regex, stroke)
        if len(points)==0:
            continue
        x_list = [int(point[0]) for point in points]
        y_list = [int(point[1]) for point in points]
        ax.plot(x_list, y_list, color='black', lw=2)

    plt.gca().invert_yaxis()  # y축 뒤집기

    # 그래프 저장
    buf = io.BytesIO()
    plt.savefig(buf, format='png', bbox_inches='tight')
    buf_resized = buf

    ## resize 작업
    buf.seek(0)
    img = Image.open(buf)
    img_resized = img.resize((150,100), Image.Resampling.LANCZOS)  
    # img_resized = img.resize((150,100), Image.ANTIALIAS)  
    # sampling=Image.ANTIALIAS deprecated 되었다. 버전에 따라 위 둘 중 하나를 사용.
    buf_resized = io.BytesIO()
    img_resized.save(buf_resized, format=img.format)

    # buf대신 buf_resized를 변환
    buf_resized.seek(0)
    data_uri = 'data:image/png;base64,'+base64.b64encode(buf_resized.read()).decode('utf-8')
    plt.close()
    plt.clf()
    plt.close('all')
    img.close()
    img_resized.close()
    buf.close()
    buf_resized.close()

    return data_uri

이 함수를 사용하여 드로잉 데이터를 넣으면, datauri 텍스트가 출력된다.

시작,끝 따옴표를 제거한 텍스트를 복사해서 브라우저 URL창에 넣으면 드로잉된 투명이미지가 나온다.. (드래그해 보면, 선만 움직이는 것을 확인할 수 있다. 배경투명)

y축을 뒤집은 이유는? 모니터 스크린 좌표계에서 보통 좌상단이 (0,0) 이다.  plot에서는 좌하단이 (0,0)이다. 따라서 스크린 좌표계로 보이게 하려고 하였다. 

datauri가 아니라 파일로 저장하려면 plt.close() 전에  plt.savefig('test.png') 로 저장하면 된다.

 

'Python' 카테고리의 다른 글

투명 배경 이미지 만들기  (0) 2023.03.22
set에 set 추가? frozenset  (0) 2021.02.24
Jupyter Notebook 소스 복구  (0) 2020.06.16
Docker python venv 패키지 유지  (0) 2020.06.07
딕셔너리에서 키삭제  (0) 2019.12.07
반응형
ViewPager가 ViewPager2 로 업데이트되면서 사용하는 방법이 바뀌었다.

상단에 탭 메뉴가 있어서 메뉴 클릭 또는 컨텐트를 좌우 슬라이드하며 다른 페이지로 변경한다.

- TabLayout을 쓰기 위해 Dependency에 별다르게 추가하지 않아도 기본으로 material이 들어가있다. 

'com.google.android.material:material:1.7.0'

- main activity layout에 tab layout 과 viewpager2 를 추가

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    >

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Monday" />

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tuesday" />

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Wednesday" />
    </com.google.android.material.tabs.TabLayout>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />

</LinearLayout>

- 각 탭별로 fragment xml 생성

frag_monday.xml, frag_tuesday.xml, frag_wednesday.xml 약간씩 바꿔서 확인.

<?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">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="170dp"
        android:layout_marginTop="349dp"
        android:layout_marginEnd="170dp"
        android:text="Monday"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

- 각 fragment 클래스 생성. 이것도 이름만 약간씩 다르게..


public class FragMonday extends Fragment {
    private View view ;
    public static FragMonday newInstance() {
        FragMonday fragMonday = new FragMonday();
        return fragMonday;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.frag_monday, container,  false) ;
        return view ;
    }

}

- Adapter를 만들어야 한다. ViewPagerAdapter class


public class ViewPagerAdapter extends FragmentStateAdapter {
    private final List<Fragment> fragmnets = new ArrayList<Fragment>() ;
    private final List<String> titles = new ArrayList<>() ;

    public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragmnets.get(position) ;
    }

    @Override
    public int getItemCount() {
        return fragmnets.size() ;
    }

    public void addFragment(@NonNull Fragment frag, String title) {
        fragmnets.add(frag) ;
        titles.add(title) ;
    }
    @NonNull
    public String getTitle(int position) {
        return titles.get(position) ;
    }

}

 

- 이제 MainActivity에서 모두 연결시킨다.


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(this);
        viewPagerAdapter.addFragment(FragMonday.newInstance(), "Monday");
        viewPagerAdapter.addFragment(FragTuesday.newInstance(), "Tuesday");
        viewPagerAdapter.addFragment(FragWednesday.newInstance(), "Wednesday");

        ViewPager2 viewPager = findViewById(R.id.viewpager);
        viewPager.setAdapter(viewPagerAdapter);

        TabLayout tabLayout = findViewById(R.id.tablayout);
        TabLayoutMediator tm = new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
            tab.setText(viewPagerAdapter.getTitle(position)) ;
        }) ;
        tm.attach();
    }
}

끝.

 

'Develop > Android' 카테고리의 다른 글

RecyclerView, Firebase DB, reload  (0) 2023.03.19
[Android] JSON 데이터 송수신  (1) 2023.03.18

+ Recent posts