포인트 리스트를 가지고 그림을 드로잉하고, 이것을 원하는 크기로 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') 로 저장하면 된다.
4. 아이템 class. User class (getter and setter 는 alt+insert키로 쉽게 자동생성 하세요.. )
public class User {
private String profile ;
private String id ;
private int pw ;
private String userName ;
5. CustomAdapter class
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private ArrayList<User> arrayList ;
private Context context ;
public CustomAdapter(ArrayList<User> arrayList, Context context) {
this.arrayList = arrayList;
this.context = context;
}
@NonNull
@Override
public CustomAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false) ;
CustomViewHolder holder = new CustomViewHolder(view) ;
return holder; // 홀더 리턴
}
@Override
public void onBindViewHolder(@NonNull CustomAdapter.CustomViewHolder holder, int position) {
Glide.with(holder.itemView)
.load(arrayList.get(position).getProfile())
.into(holder.iv_profile) ;
holder.tv_id.setText(arrayList.get(position).getId());
holder.tv_pw.setText(String.valueOf(arrayList.get(position).getPw()));
holder.tv_userName.setText(arrayList.get(position).getUserName());
}
@Override
public int getItemCount() {
return (arrayList!=null ? arrayList.size(): 0);
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
ImageView iv_profile ;
TextView tv_id ;
TextView tv_userName ;
TextView tv_pw ;
public CustomViewHolder(@NonNull View itemView) {
super(itemView);
iv_profile = itemView.findViewById(R.id.iv_profile) ;
tv_id = itemView.findViewById(R.id.tv_id) ;
tv_userName = itemView.findViewById(R.id.tv_userName) ;
tv_pw = itemView.findViewById(R.id.tv_pw) ;
}
}
}
6. Firebase 설정.
Tools - firebase 선택. (예전엔 수작업으로 한 거를 편리하게 다 해준다..)
우측에 Realtime Database 메뉴를 선택한다. Get started with Realtime Database 로 가서, 차례로 진행한다.
connect your app to firebase ; 브라우저로 구글 로그인하여 firebase 콘솔로 가서 프로젝트 생성까지 진행됨.
(실시간 DB를 잘 만든다. 필드도 User class에 맞게 다 맞춘다. +를 눌러 User를 만들고 다시 +를 눌러 User_01을 만들고 다시 +를 눌러 profile, id, pw, userName 필드들을 만든다. 처음엔 사용법을 몰라 어렵다. 하위 노드를 위해 미리 +를 연속해서 눌러줘야 된다. 미리 만들고, 엔터치면 하위에 추가가 안되서 삽질.. )
Add the Realtime Database to your app ; dependency 등을 알아서 설정해 준다.
그러나,... 나의 경우는 빌드시 에러가... 찾아보니, 버전 문제가 또 있다... (어쩌라고.. 정말 막막하게 만드는 버전 호환성...)
build.gradle (project) 에서 4.3.10 으로 들어가 있는데 찾아보니 버전을 14로 올리면 해결된다고 해서 해보니 성공하였음.
classpath 'com.google.gms:google-services:4.3.14'
7.MainActivity에서 RecyclerView와 Adapter 연결 및 Firebase 연동...