10.31 add-image-upload-labeler

yuying
王宇洋 3 years ago
parent 91d53bd1ca
commit 926aa8f9fa

@ -0,0 +1,19 @@
package com.echo.colorizeit.ML;
import org.tensorflow.lite.support.label.Category;
import java.util.List;
/**
* @Author: WangYuyang
* @Date: 2021/10/31-16:00
* @Project: My Application
* @Package: com.echo.photo_editor.ML
* @Description:
**/
public interface CategoryProcessListener {
void start();
void success(List<Category> result);
void failed(String message);
void complete();
}

@ -0,0 +1,57 @@
package com.echo.colorizeit.ML;
import android.content.Context;
import android.graphics.Bitmap;
import com.example.myapplication.ml.LiteModelObjectDetectionMobileObjectLabelerV11;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.label.Category;
import java.io.IOException;
import java.util.List;
/**
* @Author: WangYuyang
* @Date: 2021/10/31-15:58
* @Project: My Application
* @Package: com.echo.photo_editor.ML
* @Description:
**/
public class LabelerModel {
private Context context;
public LabelerModel(Context context) {
this.context = context;
}
public void process(Bitmap source, CategoryProcessListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
listener.start();
try {
LiteModelObjectDetectionMobileObjectLabelerV11 model = LiteModelObjectDetectionMobileObjectLabelerV11.newInstance(context);
// Creates inputs for reference.
TensorImage image = TensorImage.fromBitmap(source);
// Runs model inference and gets result.
LiteModelObjectDetectionMobileObjectLabelerV11.Outputs outputs = model.process(image);
List<Category> probability = outputs.getProbabilityAsCategoryList();
// Releases model resources if no longer used.
model.close();
listener.success(probability);
} catch (IOException e) {
// TODO Handle the exception
listener.failed(e.getMessage());
}
finally {
listener.complete();
}
}
}).start();
}
}

@ -8,6 +8,7 @@ import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
@ -16,6 +17,7 @@ import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
@ -23,6 +25,8 @@ import androidx.navigation.ui.AppBarConfiguration;
import com.echo.colorizeit.ImageUtil.PhotoLib;
import com.echo.colorizeit.Interfaces.RequestsListener;
import com.echo.colorizeit.ML.CategoryProcessListener;
import com.echo.colorizeit.ML.LabelerModel;
import com.echo.colorizeit.Util;
import com.echo.colorizeit.ui.BaseActivity;
import com.echo.photo_editor.photo_editor_view.PhotoEditorView;
@ -30,6 +34,11 @@ import com.echo.stinger_game.myganme.GameActivity;
import com.example.myapplication.R;
import com.example.myapplication.databinding.ImageColorizeUploadActivityBinding;
import org.tensorflow.lite.support.label.Category;
import java.util.Comparator;
import java.util.List;
import ch.halcyon.squareprogressbar.utils.PercentStyle;
/**
@ -43,6 +52,8 @@ public class ImageUploadViewActivity extends BaseActivity {
private ImageView imageDisplay;
private Uri ColorizedImageUri;
private ImageUploadViewActivity _this = this;
private LabelerModel labelerModel = new LabelerModel(this);
private LabelAdapter labelAdapter = new LabelAdapter();
@Override
@ -66,6 +77,7 @@ public class ImageUploadViewActivity extends BaseActivity {
// imageDisplay.setProgress(integer);
// }
// });
binding.lableView.setAdapter(labelAdapter);
model.setImageViewDataByPath(intent.getStringExtra("sourceFilePath"));
binding.imageProcessingAnimation.setOnClickListener(new View.OnClickListener() {
@Override
@ -155,7 +167,7 @@ public class ImageUploadViewActivity extends BaseActivity {
@Override
public void onClick(View v) {
String data = MediaStore.Images.Media.insertImage(getContentResolver(), model.getColorizedImageBitmap(), String.valueOf(System.currentTimeMillis()), ":)");
while (data== null){
while (data == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
@ -220,6 +232,44 @@ public class ImageUploadViewActivity extends BaseActivity {
PercentStyle percentStyle = new PercentStyle(Paint.Align.CENTER, 190, true);
percentStyle.setTextColor(Color.GRAY);
labelerModel.process(model.getSourceImageBitmap(), new CategoryProcessListener() {
@Override
public void start() {
}
@Override
public void success(List<Category> result) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
result.sort(new Comparator<Category>() {
@Override
public int compare(Category o1, Category o2) {
return (int) (o2.getScore() * 100 - o1.getScore() * 100);
}
});
}
for (Category c : result) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(c.getScore() >= 0.01)
labelAdapter.addLabels(c.getLabel() + ":" + c.getScore());
}
});
}
}
@Override
public void failed(String message) {
}
@Override
public void complete() {
}
});
model.processImage(new RequestsListener() {
@Override

@ -0,0 +1,71 @@
package com.echo.colorizeit.ui.a_image_upload_activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.R;
import com.example.myapplication.databinding.LableItemBinding;
import java.util.ArrayList;
import java.util.Random;
/**
* @Author: WangYuyang
* @Date: 2021/10/31-16:24
* @Project: My Application
* @Package: com.echo.colorizeit.ui.a_image_upload_activity
* @Description:
**/
public class LabelAdapter extends RecyclerView.Adapter {
private ArrayList<String> labels = new ArrayList<>();
private int[] colors = new int[]{Color.parseColor("#FF1461"), Color.parseColor("#18FF92"), Color.parseColor("#5A87FF"), Color.parseColor("#FBF38C"), Color.parseColor("#FBF38C")};
private int[] resource = new int[]{R.drawable.lablestyle, R.drawable.lablestyle1, R.drawable.lablestyle2, R.drawable.lablestyle3, R.drawable.lablestyle4};
private Random random = new Random();
public void addLabels(String label){
labels.add(label);
notifyDataSetChanged();
}
public void setLabels(ArrayList<String> labels) {
this.labels = labels;
notifyDataSetChanged();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LableItemBinding binding;
binding = LableItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
LabelViewHolder holder = new LabelViewHolder(binding.getRoot());
holder.binding = binding;
return holder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
LableItemBinding binding = ((LabelViewHolder) holder).binding;
binding.lableName.setText(labels.get(position));
// binding.lableName.setBackgroundColor(colors[random.nextInt(colors.length)]);
binding.lableName.setBackgroundResource(resource[random.nextInt(resource.length)]);
}
@Override
public int getItemCount() {
return labels.size();
}
private static class LabelViewHolder extends RecyclerView.ViewHolder {
private LableItemBinding binding;
public LabelViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}

@ -1,7 +1,6 @@
package com.echo.colorizeit.ui.f_main_index_page_view;
import static androidx.core.content.ContextCompat.checkSelfPermission;
import static com.echo.colorizeit.Util.check_is_grayscale;
import android.Manifest;
@ -35,7 +34,6 @@ import com.echo.colorizeit.Util;
import com.echo.colorizeit.ui.BaseFragment;
import com.echo.colorizeit.ui.a_image_upload_activity.ImageUploadViewActivity;
import com.echo.colorizeit.ui.v_others.ResizableImageView;
import com.echo.photo_editor.photo_editor_view.PhotoEditorView;
import com.echo.stinger_game.myganme.GameActivity;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentSlideshowBinding;
@ -46,6 +44,8 @@ import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.listener.OnResultCallbackListener;
import com.sdsmdg.harjot.rotatingtext.RotatingTextWrapper;
import org.tensorflow.lite.support.image.TensorImage;
import java.util.List;
/**
@ -145,35 +145,43 @@ public class MainIndexPageFragment extends BaseFragment {
public void onResult(List<LocalMedia> result) {
sourceFilePath = result.get(0).getRealPath();
Bitmap img = BitmapFactory.decodeFile(sourceFilePath);
if (!check_is_grayscale(img)) {
final AlertDialog.Builder alterDialog = new AlertDialog.Builder(getActivity());
alterDialog.setTitle("Is this a grayscale image ?");//文字
alterDialog.setMessage("We think the image you choose is not a grayscale image, are you sure you want to upload ?");//提示消息
alterDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getActivity(), ImageUploadViewActivity.class);
intent.putExtra("sourceFilePath", sourceFilePath);
startActivity(intent);
}
});
alterDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
alterDialog.show();
} else {
Intent intent = new Intent(getActivity(), ImageUploadViewActivity.class);
intent.putExtra("sourceFilePath", sourceFilePath);
startActivity(intent);
TensorImage image = TensorImage.fromBitmap(img);
if (image.getTensorBuffer().getFlatSize() < 10000000) {
if (!check_is_grayscale(img)) {
final AlertDialog.Builder alterDialog = new AlertDialog.Builder(getActivity());
alterDialog.setTitle("Is this a grayscale image ?");//文字
alterDialog.setMessage("We think the image you choose is not a grayscale image, are you sure you want to upload ?");//提示消息
alterDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getActivity(), ImageUploadViewActivity.class);
intent.putExtra("sourceFilePath", sourceFilePath);
startActivity(intent);
}
});
alterDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
alterDialog.show();
} else {
Intent intent = new Intent(getActivity(), ImageUploadViewActivity.class);
intent.putExtra("sourceFilePath", sourceFilePath);
startActivity(intent);
}
}
else{
showSnackbar("This image is too big, it can't be uploaded.");
}
}
@Override
public void onCancel() {
// 取消

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#4bb6ef" />
<padding android:top="5dp"
android:left="5dp"
android:right="5dp"
android:bottom="5dp" />
<corners android:radius="10dp" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF1461" />
<padding android:top="5dp"
android:left="5dp"
android:right="5dp"
android:bottom="5dp" />
<corners android:radius="10dp" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#18FF92" />
<padding android:top="5dp"
android:left="5dp"
android:right="5dp"
android:bottom="5dp" />
<corners android:radius="10dp" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#5A87FF" />
<padding android:top="5dp"
android:left="5dp"
android:right="5dp"
android:bottom="5dp" />
<corners android:radius="10dp" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FBF38C" />
<padding android:top="5dp"
android:left="5dp"
android:right="5dp"
android:bottom="5dp" />
<corners android:radius="10dp" />
</shape>

Binary file not shown.

@ -28,6 +28,7 @@
android:layout_height="80dp"
android:scaleType="fitCenter"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/backButton"
@ -38,11 +39,10 @@
<ImageView
android:id="@+id/imageDisplay"
android:layout_width="0dp"
android:layout_height="328dp"
android:layout_height="300dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="24dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="32dp"
android:gravity="center"
@ -52,10 +52,22 @@
app:layout_constraintBottom_toTopOf="@+id/ShareButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3">
app:srcCompat="@drawable/accept">
</ImageView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lable_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:spanCount="2"
app:layout_constraintBottom_toTopOf="@+id/imageDisplay"
app:layout_constraintEnd_toEndOf="@+id/imageDisplay"
app:layout_constraintStart_toStartOf="@+id/imageDisplay"
tools:listitem="@layout/lable_item" />
<com.karacce.buttom.Buttom
android:id="@+id/CompareButton"
android:layout_width="0dp"

@ -0,0 +1,23 @@
<?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="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/lable_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/lablestyle"
android:fontFamily="@font/aclonica"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,21 @@
package com.echo.photo_editor.ML;
import android.graphics.Bitmap;
import org.tensorflow.lite.support.label.Category;
import java.util.List;
/**
* @Author: WangYuyang
* @Date: 2021/10/31-16:00
* @Project: My Application
* @Package: com.echo.photo_editor.ML
* @Description:
**/
public interface CategoryProcessListener {
void start();
void success(List<Category> result);
void failed(String message);
void complete();
}

@ -6,7 +6,7 @@ import android.graphics.Bitmap;
* @author WangYuyang
* @date 2021-09-22 13:54:24
*/
public interface ProcessListener {
public interface ImageProcessListener {
void start();
void success(Bitmap FinishedBitmap);
void failed(String message);

@ -0,0 +1,57 @@
package com.echo.photo_editor.ML;
import android.content.Context;
import android.graphics.Bitmap;
import com.echo.photo_editor.ml.LiteModelObjectDetectionMobileObjectLabelerV11;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.label.Category;
import java.io.IOException;
import java.util.List;
/**
* @Author: WangYuyang
* @Date: 2021/10/31-15:58
* @Project: My Application
* @Package: com.echo.photo_editor.ML
* @Description:
**/
public class LabelerModel {
private Context context;
public LabelerModel(Context context) {
this.context = context;
}
public void process(Bitmap source, CategoryProcessListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
listener.start();
try {
LiteModelObjectDetectionMobileObjectLabelerV11 model = LiteModelObjectDetectionMobileObjectLabelerV11.newInstance(context);
// Creates inputs for reference.
TensorImage image = TensorImage.fromBitmap(source);
// Runs model inference and gets result.
LiteModelObjectDetectionMobileObjectLabelerV11.Outputs outputs = model.process(image);
List<Category> probability = outputs.getProbabilityAsCategoryList();
// Releases model resources if no longer used.
model.close();
listener.success(probability);
} catch (IOException e) {
// TODO Handle the exception
listener.failed(e.getMessage());
}
finally {
listener.complete();
}
}
}).start();
}
}

@ -6,7 +6,6 @@ import android.graphics.Bitmap;
import com.echo.photo_editor.ml.LiteModelZeroDce1;
import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.common.TensorProcessor;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;
@ -29,7 +28,7 @@ public class LowLightModel {
this.context = context;
}
public void process(Bitmap source, ProcessListener listener) {
public void process(Bitmap source, ImageProcessListener listener) {
new Thread(new Runnable() {
@Override
public void run() {

@ -7,6 +7,6 @@ import android.graphics.Bitmap;
* @date 2021-09-22 13:54:24
*/
public interface StyleMLModel {
void process(String path, ProcessListener listener);
void process(Bitmap img_style, Bitmap img_to_be_process, ProcessListener listener);
void process(String path, ImageProcessListener listener);
void process(Bitmap img_style, Bitmap img_to_be_process, ImageProcessListener listener);
}

@ -25,7 +25,7 @@ public class StyleTransModel implements StyleMLModel {
}
@Override
public void process(String path, ProcessListener listener) {
public void process(String path, ImageProcessListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
@ -65,7 +65,7 @@ public class StyleTransModel implements StyleMLModel {
}
@Override
public void process(Bitmap img_style, Bitmap img_to_be_process, ProcessListener listener) {
public void process(Bitmap img_style, Bitmap img_to_be_process, ImageProcessListener listener) {
new Thread(new Runnable() {
@Override
public void run() {

@ -10,5 +10,5 @@ import android.graphics.Bitmap;
* @Description:
**/
public interface SuperResMLModel {
void process(Bitmap source, ProcessListener listener);
void process(Bitmap source, ImageProcessListener listener);
}

@ -3,15 +3,6 @@ package com.echo.photo_editor.ML;
import android.content.Context;
import android.graphics.Bitmap;
import com.echo.photo_editor.ml.EsrganTf21;
import com.echo.photo_editor.ml.MagentaArbitraryImageStylizationV1256Fp16Prediction1;
import com.echo.photo_editor.ml.MagentaArbitraryImageStylizationV1256Fp16Transfer1;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
import java.io.IOException;
/**
* @Author: WangYuyang
* @Date: 2021/10/31-00:00
@ -27,7 +18,7 @@ public class SuperResMLModel_impl implements SuperResMLModel {
}
@Override
public void process(Bitmap source, ProcessListener listener) {
public void process(Bitmap source, ImageProcessListener listener) {
new Thread(new Runnable() {
@Override
public void run() {

@ -3,7 +3,7 @@ package com.echo.photo_editor.photo_editor_view.model;
import android.graphics.Bitmap;
import android.view.View;
import com.echo.photo_editor.ML.ProcessListener;
import com.echo.photo_editor.ML.ImageProcessListener;
import com.echo.photo_editor.photo_editor_view.PhotoEditorView;
/**
@ -19,7 +19,7 @@ public class LowLightTool extends Tool{
super.listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
view.lowLightModel.process(view.model.getEditableImage().getValue().getCurrent_bitmap(), new ProcessListener() {
view.lowLightModel.process(view.model.getEditableImage().getValue().getCurrent_bitmap(), new ImageProcessListener() {
@Override
public void start() {
view.showLoading("(On-Device ML) Processing....");

@ -4,7 +4,7 @@ package com.echo.photo_editor.photo_editor_view.model;
import android.graphics.Bitmap;
import android.view.View;
import com.echo.photo_editor.ML.ProcessListener;
import com.echo.photo_editor.ML.ImageProcessListener;
import com.echo.photo_editor.photo_editor_view.PhotoEditorView;
/**
@ -21,7 +21,7 @@ public class StyleTool extends Tool {
@Override
public void onClick(View v) {
view.styleTransModel.process(style_image, view.model.getEditableImage().getValue().getCurrent_bitmap(), new ProcessListener() {
view.styleTransModel.process(style_image, view.model.getEditableImage().getValue().getCurrent_bitmap(), new ImageProcessListener() {
@Override
public void start() {
view.showLoading("(On-Device ML) Processing....");

Loading…
Cancel
Save