Face Swap Using Face Detection Android - android

I am trying to do Face swap kind of application using facedetection. Till now i get the faces detected in bitmap and draw oval on the faces detected. But now i need to use the faces inside the oval so that i can swap two faces. Is it possible. I need some suggestions regarding this.
My activity class as follows
public class FaceDetectionActivity extends Activity
{
public MyView faceview;
public ImageView gallery;
private Uri imageURI;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
setContentView(R.layout.main);
faceview = (MyView)findViewById(R.id.faceview);
gallery=(ImageView)findViewById(R.id.gallery);
gallery.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 0 );
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if(requestCode==0){
imageURI = data.getData();
try {
Bitmap b = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), imageURI);
faceview.myBitmap=b;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
faceview.invalidate();
}
faceview.invalidate();
} else {
System.exit(0);
Log.e("result", "BAD");
}
}
}
and my view class
public class MyView extends ImageViewTouchBase {
public RectF rectF;
public Bitmap myBitmap;
private int width, height;
private FaceDetector.Face[] detectedFaces;
private int NUMBER_OF_FACES=10;
private FaceDetector faceDetector;
private int NUMBER_OF_FACE_DETECTED;
private float eyeDistance;
Matrix mImageMatrix;
public MyView(Context context, AttributeSet attrs)
{
super(context, attrs);
BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options();
bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565;
myBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.familyportrait,bitmapFatoryOptions);
width=myBitmap.getWidth();
height=myBitmap.getHeight();
detectedFaces=new FaceDetector.Face[NUMBER_OF_FACES];
faceDetector=new FaceDetector(width,height,NUMBER_OF_FACES);
NUMBER_OF_FACE_DETECTED=faceDetector.findFaces(myBitmap, detectedFaces);
}
#Override
protected void onDraw(Canvas canvas)
{
if(myBitmap!=null)
{
canvas.drawBitmap(myBitmap, 0,0, null);
}
Paint myPaint = new Paint();
myPaint.setColor(Color.GREEN);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(3);
for(int count=0;count<NUMBER_OF_FACE_DETECTED;count++)
{
Face face=detectedFaces[count];
PointF midPoint=new PointF();
face.getMidPoint(midPoint);
eyeDistance=face.eyesDistance();
float left = midPoint.x - (float)(1.4 * eyeDistance);
float right = midPoint.x + (float)(1.4 * eyeDistance);
float top = midPoint.y - (float)(1.8 * eyeDistance);
float bottom = midPoint.y + (float)(1.8 * eyeDistance);
Rect imageRect = new Rect(0, 0, width, height);
rectF = new RectF();
rectF.set(left,top,right,bottom);
canvas.drawOval(rectF, myPaint);
}
}
}
Now i want the content inside the oval to be selected. Please suggest me some ideas.

I just figured it out. I am creating another bitmap with the variables Left,Right,Top and Bottom from the above code. and then i get a square bitmap of the faces.I am extracting circular bitmap from the square bitmap faces. Thats it.

Try this code:
public class MainActivity extends ProgressA {
public static final String FACE_1 = "face_1";
public static final String FACE_2 = "face_2";
private ImageView mIvForDetect;
private ImageView mIvForDetect2;
private ImageView mIvForDetect3;
private ImageView mIvForDetect4;
//private Bitmap baseBTM;
private Bitmap face1BTM;
private Bitmap face2BTM;
boolean face1Done = false;
boolean face2Done = false;
private FirebaseVisionFaceDetector detector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mIvForDetect = findViewById(R.id.iv_main_for_detect);
mIvForDetect2 = findViewById(R.id.iv_main_for_detect2);
mIvForDetect3 = findViewById(R.id.iv_main_for_detect3);
mIvForDetect4 = findViewById(R.id.iv_main_for_detect4);
//baseBTM = BitmapFactory.decodeResource(getResources(), R.drawable.paj);
mIvForDetect.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.jolie));
mIvForDetect2.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.pitt));
detector = FirebaseVision.getInstance().getVisionFaceDetector(buildCloudVisionOptions());
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showProgressDialog();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
detectFace(mIvForDetect, FACE_1, null);
detectFace(mIvForDetect2,FACE_2, null);
}
});
thread.start();
}
});
}
private void checkFaces() {
if (face1Done && face2Done){
swapFaces();
}
}
private void swapFaces() {
detectFace(mIvForDetect, FACE_1, face2BTM);
detectFace(mIvForDetect2, FACE_2, face1BTM);
}
private void detectFace(final ImageView view, final String face, final Bitmap fakeFace) {
final Bitmap baseBTM = ((BitmapDrawable) view.getDrawable()).getBitmap();
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(baseBTM);
detector.detectInImage(image)
.addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
#Override
public void onSuccess(List<FirebaseVisionFace> faces) {
if (fakeFace != null){
setFakeFace(view, faces.get(0), baseBTM, fakeFace);
hideProgressDialog();
}else {
switch (face){
case FACE_1:
face1BTM = createTrimmedBitmap(cutFaces(faces.get(0), baseBTM));
mIvForDetect3.setImageBitmap(face1BTM);
face1Done = true;
checkFaces();
break;
case FACE_2:
face2BTM = createTrimmedBitmap(cutFaces(faces.get(0), baseBTM));
mIvForDetect4.setImageBitmap(face2BTM);
face2Done = true;
checkFaces();
break;
}
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
hideProgressDialog();
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public FirebaseVisionFaceDetectorOptions buildCloudVisionOptions() {
return new FirebaseVisionFaceDetectorOptions.Builder()
.setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
.setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
.setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
.setPerformanceMode(FirebaseVisionFaceDetectorOptions.FAST)
.build();
}
public static Bitmap createTrimmedBitmap(Bitmap bmp) {
int imgHeight = bmp.getHeight();
int imgWidth = bmp.getWidth();
int smallX = 0, largeX = imgWidth, smallY = 0, largeY = imgHeight;
int left = imgWidth, right = imgWidth, top = imgHeight, bottom = imgHeight;
for (int i = 0; i < imgWidth; i++) {
for (int j = 0; j < imgHeight; j++) {
if (bmp.getPixel(i, j) != Color.TRANSPARENT) {
if ((i - smallX) < left) {
left = (i - smallX);
}
if ((largeX - i) < right) {
right = (largeX - i);
}
if ((j - smallY) < top) {
top = (j - smallY);
}
if ((largeY - j) < bottom) {
bottom = (largeY - j);
}
}
}
}
bmp = Bitmap.createBitmap(bmp, left, top, imgWidth - left - right, imgHeight - top - bottom);
return bmp;
}
public Bitmap cutFaces(FirebaseVisionFace face, Bitmap baseBTM) {
Bitmap tempBitmap = Bitmap.createBitmap(baseBTM.getWidth(), baseBTM.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(baseBTM, 0, 0, null);
int top = face.getBoundingBox().top;
int left = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR).getPosition().getX());
int right = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.RIGHT_EAR).getPosition().getX());
int bottom = face.getBoundingBox().bottom;
Bitmap output = Bitmap.createBitmap(tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
canvas.drawOval(left, top, right, bottom, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(tempBitmap, new Matrix(), paint);
return output;
}
public void setFakeFace(ImageView view, FirebaseVisionFace face, Bitmap baseBTM, Bitmap fakeFace) {
Bitmap resultBitmap = Bitmap.createBitmap(baseBTM.getWidth(), baseBTM.getHeight(), baseBTM.getConfig());
Canvas canvas = new Canvas(resultBitmap);
final Paint paintSRC = new Paint();
final Paint paintDST = new Paint();
int top = face.getBoundingBox().top;
int left = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR).getPosition().getX());
int right = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.RIGHT_EAR).getPosition().getX());
int bottom = face.getBoundingBox().bottom;
int weight = right - left;
int height = bottom - top;
canvas.drawOval(left, top, right, bottom, paintSRC);
paintSRC.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
paintDST.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
Matrix matrix = new Matrix();
matrix.postScale(face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR).getPosition().getX(), face.getBoundingBox().top);
canvas.drawBitmap(baseBTM, 0, 0, null);
canvas.drawBitmap(Bitmap.createScaledBitmap(fakeFace, weight, height, false), left, top, paintDST);
view.setImageBitmap(resultBitmap);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} }

Related

After drawing painting, changing brush then whole painted color is change to according to that brush effect for canvas drawing in android

I am done creating different brush effect in for canvas. When i change the brush then previously drawn paint is change to that brush effect. So what i do for that? If any guidance then please provide me.
Below is my DrawingView class.
public class DrawingView extends View
{
private final Paint mPaintSrcIn = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
private final Paint mPaintDstIn = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
public Paint mPaintColor = new Paint(Paint.ANTI_ALIAS_FLAG);
public Paint mPaintColor1 = new Paint(Paint.ANTI_ALIAS_FLAG);
// public final Paint mPaintColor2 = new Paint(Paint.ANTI_ALIAS_FLAG);
// public final Paint mPaintColor3 = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintEraser = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Matrix mMatrix = new Matrix();
private final Canvas mLayerCanvas = new Canvas();
private Bitmap mInnerShape;
private Bitmap mOuterShape;
private Bitmap mLayerBitmap;
private Color mInnerColor,mOuterColor;
PlayActivity playActivity = new PlayActivity();
private int mFlag;
private int paintAlpha = 255;
private int paintColor = 0xFFFF0000;
private ArrayList<DrawOp> mDrawOps = new ArrayList<DrawOp>();
private ArrayList<DrawOp> mDrawOps1 = new ArrayList<DrawOp>();
private DrawOp mCurrentOp = new DrawOp();
private DrawOp mPreviousOp = new DrawOp();
private ArrayList<DrawOp> mUndoneOps = new ArrayList<DrawOp>();
public DrawingView(Context context)
{
this(context, null, 0);
}
public DrawingView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public DrawingView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mPaintSrcIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
mPaintDstIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintEraser.set(mPaintColor);
mPaintEraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaintEraser.setMaskFilter(new BlurMaskFilter(getResources()
.getDisplayMetrics().density * 4, BlurMaskFilter.Blur.NORMAL));
}
public void setShape(int inner, int outer)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
setShape(BitmapFactory.decodeResource(getResources(), inner, options),
BitmapFactory.decodeResource(getResources(), outer, options));
}
public void setShape(Bitmap inner, Bitmap outer)
{
mInnerShape = inner;
mOuterShape = outer;
requestLayout();
invalidate();
}
public void setDrawingColor(int color)
{
mCurrentOp.reset();
mCurrentOp.type = DrawOp.Type.PAINT;
mCurrentOp.color = color;
mPreviousOp.reset();
mPreviousOp.type = DrawOp.Type.PAINT;
mPreviousOp.color = color;
}
public void setDrawingStroke(int stroke)
{
mCurrentOp.reset();
mCurrentOp.type = DrawOp.Type.PAINT;
mCurrentOp.stroke = stroke;
}
public void enableEraser()
{
mCurrentOp.reset();
mCurrentOp.type = DrawOp.Type.ERASE;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
mLayerBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mLayerCanvas.setBitmap(mLayerBitmap);
if(mOuterShape != null){
int dx = (w - mOuterShape.getWidth()) / 2;
int dy = (h - mOuterShape.getHeight()) / 2;
mMatrix.setTranslate(dx, dy);
}
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if(isInEditMode()){
return;
}
// NOTE: Without extra bitmap or layer.. but HW Acceleration does not support setMaskFilter which means
// eraser has strong edges whilst drawing.
// #see http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
System.out.println("Flag before if "+mFlag);
if(mFlag==0){
System.out.println("Flag = 0 "+mFlag);
// Clear software canvas
// mPaintColor1 = mPaintColor;
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintColor.setMaskFilter(null);
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for (DrawOp op : mDrawOps) {
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
System.out.println("Drawing Flag : " + mFlag);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn);
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
}else if(mFlag==1){
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintColor.setMaskFilter(null);
// Clear software canvas
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for(DrawOp op : mDrawOps){
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn);
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
canvas.save();
}
else if(mFlag==2){
System.out.println("Flag = 2 "+mFlag);
// mPaintColor1 = mPaintColor;
/* Blur Effect for creating more effect then change following properties
BlurMaskFilter.Blur.INNER,BlurMaskFilter.Blur.NORMAL,BlurMaskFilter.Blur.OUTER
BlurMaskFilter.Blur.SOLID*/
// Code Here
BlurMaskFilter mBlur = new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL);
mPaintColor.setMaskFilter(mBlur);
// Clear software canvas
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for (DrawOp op : mDrawOps) {
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn); /*mPaintDstIn*/
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
canvas.save();
}
else if(mFlag==3){
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintColor.setMaskFilter(null);
mPaintColor.setMaskFilter(new EmbossMaskFilter(new float[] { 1, 1, 1 },0.4f, 10, 8.2f));
// Clear software canvas
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for (DrawOp op : mDrawOps) {
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn);
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
canvas.save();
}
}
private void drawOp(Canvas canvas, DrawOp op)
{
if(op.path.isEmpty()){
return;
}
final Paint paint;
if(op.type == DrawOp.Type.PAINT){
paint = mPaintColor;
paint.setColor(op.color);
paint.setStrokeWidth(op.stroke);
}else{
paint = mPaintEraser;
paint.setStrokeWidth(op.stroke);
}
mLayerCanvas.drawPath(op.path, paint);
}
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouchEvent(MotionEvent event)
{
final float x = event.getX();
final float y = event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mUndoneOps.clear();
mCurrentOp.path.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
for(int i = 0; i < event.getHistorySize(); i++){
mCurrentOp.path.lineTo(event.getHistoricalX(i), event.getHistoricalY(i));
}
mCurrentOp.path.lineTo(x, y);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mCurrentOp.path.lineTo(x, y);
mDrawOps.add(new DrawOp(mCurrentOp));
mCurrentOp.path.reset();
break;
}
invalidate();
return true;
}
private static class DrawOp
{
public final Path path = new Path();
public Type type;
public int color;
public int stroke;
public DrawOp()
{
//
}
public void reset()
{
this.path.reset();
}
public DrawOp(DrawOp op)
{
this.path.set(op.path);
this.type = op.type;
this.color = op.color;
this.stroke = op.stroke;
}
public static enum Type
{
PAINT, ERASE;
}
}
public void setFlag(int flag) {
System.out.println("Before Set mFlag " + mFlag);
this.mFlag = flag;
System.out.println("After Set mFlag " + mFlag);
}
}
This is my Activity Class for changing brush effect using button click
public class PlayActivity extends Activity{
private DrawingView mDrawingView;
private ViewGroup mBrushPanel;
private ViewGroup mBrushColors;
private SeekBar mBrushStroke;
private ViewGroup brush_panel_pencil;
private ViewGroup brush_colors_pencil;
private SeekBar brush_stroke_pencil;
String imagName ="";
private static String APP_ID = "788092211287311";
// Instance of Facebook Class
private Facebook facebook;
private AsyncFacebookRunner mAsyncRunner;
String FILENAME = "AndroidSSO_data";
private SharedPreferences mPrefs;
public boolean flag = false;
String name="";
File file = null;
FileOutputStream fOut = null;
// see:
// http://stackoverflow.com/questions/25758294/how-to-fill-different-color-on-same-area-of-imageview-color-over-another-color/
static int[] COLORS = { Color.rgb(255, 51, 255), // DARK PINK
Color.rgb(255, 230, 102), // LIGHT YELLOW
Color.rgb(148, 66, 50), // DARK MAROON
Color.rgb(186, 123, 68), // LIGHT MAROON
Color.rgb(252, 20, 20), // RED
Color.rgb(102, 255, 255), // LIGHT BLUE
Color.rgb(70, 78, 202), // DARK BLUE
Color.rgb(190, 255, 91), // LIGHT GREEN
Color.rgb(15, 230, 0), // DARK GREEN
Color.rgb(123, 0, 230), // JAMBLI
Color.rgb(255, 187, 50), // ORANGE
Color.rgb(7, 5, 0), // BLACK
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setBackgroundDrawable(
Utils.createCheckerBoard(getResources(), 16));
setContentView(R.layout.activity_play);
mDrawingView = (DrawingView) findViewById(R.id.drawing_view);
// mDrawingView.setShape(R.drawable.img_a_inner, R.drawable.img_a);
mDrawingView.setShape(R.drawable.inner, R.drawable.outer);
mDrawingView.setDrawingColor(getResources().getColor(R.color.ab_color));
mDrawingView.setFlag(0);
mBrushPanel = (ViewGroup) findViewById(R.id.brush_panel);
mBrushColors = (ViewGroup) findViewById(R.id.brush_colors);
mBrushStroke = (SeekBar) findViewById(R.id.brush_stroke);
mBrushStroke
.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar,
int progress, boolean fromUser) {
mDrawingView.setDrawingStroke(progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
});
mBrushStroke.setProgress(30);
mBrushPanel.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
mBrushPanel.getViewTreeObserver()
.removeOnPreDrawListener(this);
mBrushPanel
.setTranslationY(isLandscape() ? -mBrushPanel
.getHeight() : mBrushPanel.getHeight());
return false;
}
});
createBrushPanelContent();
}
#SuppressWarnings("null")
private void createBrushPanelContent() {
TableRow tableRow = null;
final int rowLimit = isLandscape() ? 16 : 8;
for (int i = 0; i < COLORS.length; i++) {
if ((i % rowLimit) == 0) {
tableRow = new TableRow(this);
mBrushColors.addView(tableRow, new TableLayout.LayoutParams(
WRAP_CONTENT, WRAP_CONTENT));
}
tableRow.addView(createToolButton(tableRow,
R.drawable.ic_paint_splot, i));
}
/*tableRow.addView(createToolButton1(tableRow, R.drawable.ic_paint_splot,
1));*/
}
private void showBrushPanel() {
mBrushPanel.animate().translationY(0).start();
}
private void hideBrushPanel() {
mBrushPanel
.animate()
.translationY(
isLandscape() ? -mBrushPanel.getHeight() : mBrushPanel
.getHeight()).start();
}
private boolean isLandscape() {
return getResources().getBoolean(R.bool.is_landscape);
}
private ImageButton createToolButton(ViewGroup parent, int drawableResId,
int index) {
ImageButton button = (ImageButton) getLayoutInflater().inflate(
R.layout.button_paint_spot, parent, false);
button.setImageResource(drawableResId);
button.setOnClickListener(mButtonClick);
if (index != -1) {
button.setTag(Integer.valueOf(index));
button.setColorFilter(COLORS[index]);
}
return button;
}
/* private Button createToolButton1(ViewGroup parent, int drawableResId,
int index) {
Button buttonShare = (Button) getLayoutInflater().inflate(
R.layout.button, parent, false);
buttonShare.setOnClickListener(mButtonShare);
return buttonShare;
}
};*/
private View.OnClickListener mButtonClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
// code for set the shadow color
// mDrawingView.mPaintColor.setShadowLayer(10, 10, 5, Color.RED);
mDrawingView.setDrawingColor(COLORS[((Integer) v.getTag())
.intValue()]);
hideBrushPanel();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_play, menu);
return super.onCreateOptionsMenu(menu) | true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_emboss:
mDrawingView.setFlag(3);
System.out.println("mClick Emboss");
mDrawingView.setDrawingStroke(30);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_watermark:
mDrawingView.setFlag(2);
mDrawingView.setDrawingStroke(30);
BlurMaskFilter mBlur = new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL);
mDrawingView.mPaintColor.setMaskFilter(mBlur);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_pencil:
mDrawingView.setFlag(1);
mDrawingView.setDrawingStroke(4);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_brush:
mDrawingView.setFlag(0);
mDrawingView.setDrawingStroke(30);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_eraser:
mDrawingView.enableEraser();
break;
case R.id.action_undo:
mDrawingView.undoOperation();
break;
case R.id.action_redo:
mDrawingView.redoOperation();
break;
case R.id.action_save: {
mDrawingView
.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mDrawingView.setDrawingCacheEnabled(true);
mDrawingView.buildDrawingCache();
Bitmap viewCache = mDrawingView.getDrawingCache();
Bitmap bitmap = viewCache.copy(viewCache.getConfig(), false);
mDrawingView.setDrawingCacheEnabled(false);
new SaveTask().execute(bitmap);
View view = findViewById(R.id.relative);
view.setDrawingCacheEnabled(true);
// Bitmap bitmap2 = view.getDrawingCache();
final Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_8888,
true);
final BitmapDrawable bitmapDrawable = new BitmapDrawable(
bitmap2);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.horizon,
(ViewGroup) findViewById(R.id.main_relative_output));
RelativeLayout rl = (RelativeLayout) layout
.findViewById(R.id.main_relative_output);
/*AlertDialog builder = new AlertDialog.Builder(
PlayActivity.this).setView(layout).show();*/
//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap2.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Intent i = new Intent(PlayActivity.this, SharingScreen.class);
i.putExtra("image",byteArray);
i.putExtra("name", name);
startActivity(i);
// rl.setBackgroundDrawable(bitmapDrawable);
}
break;
case R.id.action_cancel:
mDrawingView.clearDrawing();
// file.delete();
/*if(viewCache.isRecycled()){
viewCache.recycle();
bitmap.recycle();
}*/
break;
/*case R.id.action_share:
mDrawingView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mDrawingView.setDrawingCacheEnabled(true);
mDrawingView.buildDrawingCache();
Bitmap viewCache = mDrawingView.getDrawingCache();
Bitmap bitmap = viewCache.copy(viewCache.getConfig(), false);
new SaveAndShare().execute(bitmap);
break;*/
default:
return super.onOptionsItemSelected(item);
}
return true;
}
}

saving drawing to sdcard from a custom view android

I'm working an app which is can draw on a custom view. I want to save the drawing with a button. I tried the other solution on the other threads but nothing. please give me an example with my method below. actually, it's not my method. it's from https://github.com/msiuts/FingerPaint
Custom View
DrawView.java
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
private final Random random = new Random();
private final int[] colors = new int[] {Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK,
Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK};
private final Paint paint = new Paint();
private Path path = new Path();
private Canvas canvas;
private Bitmap bitmap;
// deletes the screen by painting it black when the Menu Button is pressed
// this is a good method but how about save the drawing?
private OnKeyListener clearingOnKeyListener = new OnKeyListener() {
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (KeyEvent.KEYCODE_MENU == keyEvent.getKeyCode() && KeyEvent.ACTION_DOWN == keyEvent.getAction()) {
bitmap.eraseColor(Color.BLACK);
invalidate();
return true;
}
return false;
}
};
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
this.setOnKeyListener(clearingOnKeyListener);
paint.setColor(randomColor());
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (bitmap != null) {
if (bitmap.getHeight() == w && bitmap.getWidth() == h) {
Log.d(TAG, "rotating bitmap by 90 degree");
Matrix mtx = new Matrix();
mtx.postRotate(90, h/2, w/2);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, h, w, mtx, false);
canvas = new Canvas();
canvas.setBitmap(bitmap);
return;
} else {
bitmap.recycle();
}
}
canvas = new Canvas();
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmap);
}
#Override
public void onDraw(Canvas c) {
// draw to the screen
c.drawBitmap(bitmap, null, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), null);
}
public boolean onTouch(View view, MotionEvent event) {
// draw the new Points to our internal canvas / bitmap
if (event.getAction() == MotionEvent.ACTION_DOWN) {
paint.setColor(randomColor());
path = new Path();
path.moveTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
int historySize = event.getHistorySize();
for (int i=0; i < historySize; i++) {
path.lineTo(event.getHistoricalX(i), event.getHistoricalY(i));
}
path.lineTo(event.getX(), event.getY());
canvas.drawPath(path, paint);
} else {
return super.onTouchEvent(event);
}
invalidate();
return true;
}
public Bitmap getBitmap() {
return bitmap;
}
public void initBitmap(Bitmap bmap) {
bitmap = bmap;
}
/**
* Chooses a random color.
* #return the chosen color
*/
private int randomColor() {
return colors[random.nextInt(colors.length)];
}
}
Activity
Drawing Activity.java
public class DrawingActivity extends Activity {
private static final String TAG = "FingerPaint";
private DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw);
// restore view
drawView = (DrawView) findViewById(R.id.drawView);
Log.d(TAG, "DrawView from R is null? " + (drawView == null));
Bitmap lastDrawing = (Bitmap) getLastNonConfigurationInstance();
if (lastDrawing != null) {
Log.d(TAG, "lastDrawing is not null");
drawView.initBitmap(lastDrawing);
}
}
#Override
public Object onRetainNonConfigurationInstance() {
Bitmap bmap = null;
if (drawView != null) {
bmap = drawView.getBitmap();
Log.d(TAG, "onRetainNonConfigurationInstance returning a bitmap: " + (bmap != null));
}
return bmap;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
On the assumption you want to save the file to the devices storage, here is the solution i use...
Add permission to manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Here is how I am doing it:
// Variables i needed
private String mFileName;
private Bitmap mBitmap;
// apply this listener to your button
private final View.OnClickListener ButtonListener = new View.OnCickListener(){
#Override
public void onClick(View v){
new SaveFile().execute();
}
}
private class SaveFile extends AsyncTask<Void, Void, File>{
#Override
protected File doInBackground(Void... params) {
View rootView = findViewById(R.id.drawView);
File newBackgroundBitmap = saveFileToStorage(rootView);
return newBackgroundBitmap;
}
#Override
protected void onPostExecute(File bitmapFile) {
super.onPostExecute(bitmapFile);
if(bitmapFile != null){
Toast.makeText(getBaseContext(), "Saved drawView to storage", Toast.LENGTH_SHORT).show();
}
}
}
Then here is the method doing all the work:
/**
* Saves the Bitmap File to Storage and returns the new File
* #param rootView - the View we want to capture
* #return returns the new FileName of the image.
*/
private File saveFileToStorage(View rootView){
rootView.setDrawingCacheEnabled(true);
mBitmap = rootView.getDrawingCache();
File fileDirectory = new File(Environment.getExternalStorageDirectory() + "FOLDER_NAME_YOU_WANT_TO_USE");
fileDirectory.mkdirs();
// Filename to store, Probably want to add some time stamp to make this unique
mFileName = "YOUR_FILE_NAME"+ ".png";
final File newBackgroundBitmap = new File(fileDirectory, mFileName);
try{
newBackgroundBitmap.createNewFile();
FileOutputStream outputStream = new FileOutputStream(newBackgroundBitmap);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
Log.d(TAG, "File saved..." + " " + mFileName);
}catch(Exception e){
e.printStackTrace();
}
return newBackgroundBitmap;
}

ColorPickerDialog in android while using the SPen and SCanvas?

Am am trying to use a color picker change request with the SPen, I did not want to use the one they supplied I wanted to use my own.
here is my code below, the color picker comes up, but when i select a color it doesnt change the input of the PEN
public class numberTrace extends Activity implements OnInitListener, ColorPickerDialog.OnColorChangedListener {
private Paint mPaint;
Context mContext = null;
private RelativeLayout mCanvasContainer;
private SCanvasView mSCanvas;
private ImageView mEraserBtn;
private ImageView mNextBtn;
private ImageView mPenBtn;
public int currentNumber;
int[] myImageList = { R.drawable.numbers0, R.drawable.numbers1,
R.drawable.numbers2, R.drawable.numbers3, R.drawable.numbers4,
R.drawable.numbers5, R.drawable.numbers6, R.drawable.numbers7,
R.drawable.numbers8, R.drawable.numbers9 };
int cIndex = 0;
float speechRate = 1 / 4;
private TextToSpeech tts;
String[] speakNumbers = { "Number zero", "Number one", "Number two", "Number three", "Number four",
"Number five", "Number six", "Number seven", "Number eight", "Number nine" };
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.trace); // This is calling the layout in the
// main.xml file if I change the
// main.xml file name then I would
// Create the SCanvasView
tts = new TextToSpeech(this, this);
mContext = this;
mCanvasContainer = (RelativeLayout) findViewById(R.id.canvas_container);
mSCanvas = new SCanvasView(mContext);
mCanvasContainer.addView(mSCanvas);
mEraserBtn = (ImageView) findViewById(R.id.eraserBtn);
mNextBtn = (ImageView) findViewById(R.id.nextBtn);
mPenBtn = (ImageView) findViewById(R.id.penBtn);
mPaint = new Paint();
// on button click
// setting the background of the canvas
mSCanvas.setBackgroundResource(R.drawable.numbers0);
SCanvasInitializeListener mSCanvasListener = new SCanvasInitializeListener() {
public void onInitialized() {
// --------------------------------------------
// Start SCanvasView/CanvasView Task Here
// --------------------------------------------
// Application Identifier Setting
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_PEN);
// Get the direction of contents(Canvas)
if (mSCanvas.getWidth() > mSCanvas.getHeight()) {
} else {
}
}
};
// ------------------------------------------------
// History Change
// ------------------------------------------------
HistoryUpdateListener mHistoryListener = new HistoryUpdateListener() {
public void onHistoryChanged(boolean undoable, boolean redoable) {
mNextBtn.setEnabled(undoable);
}
};
// ------------------------------------------------
// OnSettingStrokeChangeListener Listener
// ------------------------------------------------
SettingStrokeChangeListener mSettingStrokeChangeListener = new SettingStrokeChangeListener() {
public void onClearAll(boolean bClearAllCompleted) {
// If don't set eraser mode, then change to pen mode
// automatically.
if (bClearAllCompleted)
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_ERASER);
}
public void onEraserWidthChanged(int eraserWidth) {
}
public void onStrokeColorChanged(int strokeColor) {
}
public void onStrokeStyleChanged(int strokeStyle) {
}
public void onStrokeWidthChanged(int strokeWidth) {
}
public void onStrokeAlphaChanged(int strokeAlpha) {
}
};
mSCanvas.setSCanvasInitializeListener(mSCanvasListener);
mSCanvas.setSettingStrokeChangeListener(mSettingStrokeChangeListener);
mSCanvas.setColorPickerColorChangeListener(new ColorPickerColorChangeListener(){
#Override
public void onColorPickerColorChanged(int nColor) {
mPaint = new Paint();
int nCurMode = mSCanvas.getCanvasMode();
if(nCurMode==SCanvasConstants.SCANVAS_MODE_INPUT_PEN) {
SettingStrokeInfo strokeInfo = mSCanvas.getSettingViewStrokeInfo();
if(strokeInfo != null) {
strokeInfo.setStrokeColor(mPaint.getColor());
mSCanvas.setSettingViewStrokeInfo(strokeInfo);
}
}
}
});
mNextBtn.setOnClickListener(new OnClickListener() {
int i = 1;
#SuppressWarnings("deprecation")
public void onClick(View v) {
// TODO Auto-generated method stub
mSCanvas.clear();
mSCanvas.setBackgroundResource(myImageList[i]);// calling the
// array to mvoe
// to the next
// image
String speakNow = speakNumbers[cIndex];
tts.setSpeechRate(speechRate);
tts.speak(speakNow, TextToSpeech.QUEUE_FLUSH, null);
cIndex++;
cIndex %= speakNumbers.length;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if (i >= myImageList.length) {
i = 0;
// erasing the drawings on the array
}
mNextBtn.setEnabled(mSCanvas.isUndoable());
}
});
mEraserBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
int nBtnID = mEraserBtn.getId();
// If the mode is not changed, open the setting view. If the
// mode is same, close the setting view.
if (nBtnID == mEraserBtn.getId()) {
if (mSCanvas.getCanvasMode() == SCanvasConstants.SCANVAS_MODE_INPUT_ERASER) {
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_ERASER);
} else {
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_ERASER);
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_ERASER);
}
}
}
});
mPenBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mPaint = new Paint();
new ColorPickerDialog(numberTrace.this, numberTrace.this, mPaint.getColor()).show();
boolean bIsColorPickerMode = !mSCanvas.isColorPickerMode();
mSCanvas.setColorPickerMode(bIsColorPickerMode);
if (mPenBtn.equals(mPenBtn)) {
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_PEN);
mSCanvas.getColorPickerColor(mPaint.getColor(), mPaint.getColor());
}
}
});
// Caution:
// Do NOT load file or start animation here because we don't know canvas
// size here.
// Start such SCanvasView/CanvasView Task at onInitialized() of
// SCanvasInitializeListener
mSCanvas.setSCanvasInitializeListener(mSCanvasListener);
mSCanvas.setHistoryUpdateListener(mHistoryListener);
mNextBtn.setEnabled(false);
// Caution:
// Do NOT load file or start animation here because we don't know canvas
// size here.
// Start such SCanvasView/CanvasView Task at onInitialized() of
// SCanvasInitializeListener
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_PEN);
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_ERASER);
if (mSCanvas.getCanvasMode() == SCanvasConstants.SCANVAS_MODE_INPUT_PEN)
;
{
// Processed when the current mode of the SCanvasView is the Pen
// mode
}
}
public void onInit(int status) {
// TODO Auto-generated method stub
tts.setLanguage(Locale.US);
}
public void onDestroy() {
super.onDestroy();
tts.shutdown();
}
#Override
public void colorChanged(int color) {
// TODO Auto-generated method stub
SettingStrokeInfo strokeInfo = mSCanvas.getSettingViewStrokeInfo();
if(strokeInfo != null) {
strokeInfo.setStrokeColor(mPaint.getColor());
}
}
below is going to be the colorPicker class
public class ColorPickerDialog extends Dialog {
public interface OnColorChangedListener {
void colorChanged(int color);
}
private OnColorChangedListener mListener;
private int mInitialColor;
private static class ColorPickerView extends View {
private Paint mPaint;
private Paint mCenterPaint;
private final int[] mColors;
private OnColorChangedListener mListener;
ColorPickerView(Context c, OnColorChangedListener l, int color) {
super(c);
mListener = l;
mColors = new int[] {
0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
0xFFFFFF00, 0xFFFF0000
};
Shader s = new SweepGradient(0, 0, mColors, null);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(32);
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(5);
}
private boolean mTrackingCenter;
private boolean mHighlightCenter;
#Override
protected void onDraw(Canvas canvas) {
float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
canvas.translate(CENTER_X, CENTER_X);
canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
if (mTrackingCenter) {
int c = mCenterPaint.getColor();
mCenterPaint.setStyle(Paint.Style.STROKE);
if (mHighlightCenter) {
mCenterPaint.setAlpha(0xFF);
} else {
mCenterPaint.setAlpha(0x80);
}
canvas.drawCircle(0, 0,
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
mCenterPaint);
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}
private static final int CENTER_X = 100;
private static final int CENTER_Y = 100;
private static final int CENTER_RADIUS = 32;
private int floatToByte(float x) {
int n = java.lang.Math.round(x);
return n;
}
private int pinToByte(int n) {
if (n < 0) {
n = 0;
} else if (n > 255) {
n = 255;
}
return n;
}
private int ave(int s, int d, float p) {
return s + java.lang.Math.round(p * (d - s));
}
private int interpColor(int colors[], float unit) {
if (unit <= 0) {
return colors[0];
}
if (unit >= 1) {
return colors[colors.length - 1];
}
float p = unit * (colors.length - 1);
int i = (int)p;
p -= i;
// now p is just the fractional part [0...1) and i is the index
int c0 = colors[i];
int c1 = colors[i+1];
int a = ave(Color.alpha(c0), Color.alpha(c1), p);
int r = ave(Color.red(c0), Color.red(c1), p);
int g = ave(Color.green(c0), Color.green(c1), p);
int b = ave(Color.blue(c0), Color.blue(c1), p);
return Color.argb(a, r, g, b);
}
private int rotateColor(int color, float rad) {
float deg = rad * 180 / 3.1415927f;
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
ColorMatrix cm = new ColorMatrix();
ColorMatrix tmp = new ColorMatrix();
cm.setRGB2YUV();
tmp.setRotate(0, deg);
cm.postConcat(tmp);
tmp.setYUV2RGB();
cm.postConcat(tmp);
final float[] a = cm.getArray();
int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
return Color.argb(Color.alpha(color), pinToByte(ir),
pinToByte(ig), pinToByte(ib));
}
private static final float PI = 3.1415926f;
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX() - CENTER_X;
float y = event.getY() - CENTER_Y;
boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
if (inCenter) {
mHighlightCenter = true;
invalidate();
break;
}
case MotionEvent.ACTION_MOVE:
if (mTrackingCenter) {
if (mHighlightCenter != inCenter) {
mHighlightCenter = inCenter;
invalidate();
}
} else {
float angle = (float)java.lang.Math.atan2(y, x);
// need to turn angle [-PI ... PI] into unit [0....1]
float unit = angle/(2*PI);
if (unit < 0) {
unit += 1;
}
mCenterPaint.setColor(interpColor(mColors, unit));
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (mTrackingCenter) {
if (inCenter) {
mListener.colorChanged(mCenterPaint.getColor());
}
mTrackingCenter = false; // so we draw w/o halo
invalidate();
}
break;
}
return true;
}
}
public ColorPickerDialog(Context context,
OnColorChangedListener listener,
int initialColor) {
super(context);
mListener = listener;
mInitialColor = initialColor;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener() {
public void colorChanged(int color) {
mListener.colorChanged(color);
dismiss();
}
};
setContentView(new ColorPickerView(getContext(), l, mInitialColor));
setTitle("Pick a Color");
}
}
What and where do i need to change so that the SPen will write in the color chosen by the ColoPickerDialog class?
again everything works properly, just after choosing a color, the color writing stays black.
The way this was done was by Making a new settings View because as you can see above it was trying to get the settings view that was there, but I was not using the samsung settings view I was using my own color picking dialog. was trying to change the color of the stroke. The way this was done was by implementing the code below.
#Override
public void colorChanged(int color) {
// TODO Auto-generated method stub
mPaint.setColor(color);
final int pColor = mPaint.getColor();
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_PEN);
int nCurMode = mSCanvas.getCanvasMode();
if(nCurMode==SCanvasConstants.SCANVAS_MODE_INPUT_PEN)
{
SettingStrokeInfo strokeInfo = new SettingStrokeInfo();
speakNow.setBackgroundColor(pColor);
strokeInfo.setStrokeColor(pColor);
mSCanvas.setSettingStrokeInfo(strokeInfo);
}
}
The Pen Button
mPenBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mPenBtn.equals(mPenBtn)) {
mSCanvas.setCanvasMode(SCanvasConstants.SCANVAS_MODE_INPUT_PEN);
}
mPaint = new Paint();
new ColorPickerDialog(numberTrace.this, numberTrace.this, mPaint.getColor()).show();
}
});
That should help anyone else who is having the same problem.

how to solve out of memory bitmap size exceeds exception in android [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Bitmap recycle with largeHeap enabled
hi am doing one app here i am displying images using bitmaps,that images is displaying well,but becz this class i am getting out of memory exception in another class.pls see once my code and how to solve this issue any suhhest me...
public class DesignofatozActivity extends Activity {
BitmapDrawable sounddrawable,erasedrawable,backdrwable,fwddrwable,captiondrwable;
Bitmap soundbitmap,eraseBitmap,backbitmap,fwdbitmap,captionbitmap;
bitmapOrg,bitmapOrg1,bitmapOrg2,bitmapOrg3,bitmapOrg4,bitmapOrg5,bitmapOrg6;
MyView myview;
File f;
ImageView d1,d2,d3,d4,d5,d6;
public boolean action=false;
RelativeLayout relativeLayout,layout,relativeLayout2;
Button c1,c2,c3,c4,c5,c6,c7,c8;
MediaPlayer player;
MediaPlayer mediay2;
ImageView horn;
float screenHeight,screenWidth,screendensity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setNoTitle();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
screenHeight = displaymetrics.heightPixels;
screenWidth = displaymetrics.widthPixels;
screendensity = displaymetrics.densityDpi;
Log.i("screenHeight",""+screenHeight);
Log.i("screenWidth",""+screenWidth);
Log.i("screendensity",""+screendensity);
setContentView(R.layout.line);
relativeLayout=(RelativeLayout)findViewById(R.id.relative);
relativeLayout.setBackgroundColor(Color.WHITE);
relativeLayout2=(RelativeLayout)findViewById(R.id.relative2);
RelativeLayout.LayoutParams layoutrel2= (RelativeLayout.LayoutParams) relativeLayout2.getLayoutParams();
layoutrel2.height=(int)(25*(screenHeight/600));
int toplay=(int)(90*(screenHeight/600));
layout=new RelativeLayout(this);
RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(0, toplay, 0,0);
layout.setLayoutParams(lp);
relativeLayout.addView(layout,lp);
int topmyvi=(int)(45*(screenHeight/600));
myview = new MyView(this);
myview.setId(004);
RelativeLayout.LayoutParams lp6 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
myview.setLayoutParams(lp6);
lp6.setMargins(0, topmyvi, 0,0);
relativeLayout.addView(myview,lp6);
ImageView I2=new ImageView(this);
if(captiondrwable!= null) {
captionbitmap.recycle();
captiondrwable= null;
}
captionbitmap=BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.caption22_1));
captiondrwable = new BitmapDrawable(captionbitmap);
I2.setBackgroundDrawable(captiondrwable);
int left2=(int)(15*(screenWidth/1024));
int widthhh2=(int)(100*(screenWidth/1024));
int hifhtttt2=(int)(50*(screenHeight/600));
RelativeLayout.LayoutParams rlp2=new RelativeLayout.LayoutParams(widthhh2,hifhtttt2);
rlp2.setMargins(left2, topmyvi, 0, 0);
relativeLayout.addView(I2,rlp2);
ImageView b1=new ImageView(this);
if(erasedrawable!= null) {
eraseBitmap.recycle();
erasedrawable= null;
}
eraseBitmap=BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.eraser_501));
erasedrawable = new BitmapDrawable(eraseBitmap);
b1.setBackgroundDrawable(erasedrawable);
int leftb1=(int)(650*(screenWidth/1024));
int topb1=(int)(10*(screenHeight/600));
int widtb1=(int)(100*(screenWidth/1024));
int hightb1=(int)(100*(screenHeight/600));
RelativeLayout.LayoutParams rlp3=new RelativeLayout.LayoutParams(widtb1,hightb1);
rlp3.setMargins(leftb1, topb1, 0, 0);
relativeLayout.addView(b1,rlp3);
b1.setOnClickListener(new OnClickListener() {
// #Override
public void onClick(View v) {
// TODO Auto-generated method stub
try{
mBitmap.eraseColor(android.graphics.Color.TRANSPARENT);
Canvas Canvas=new Canvas(mBitmap);
action=true;
myview.onDraw(Canvas);
}catch(IllegalStateException ie){
ie.printStackTrace();
}
}
});
int lefth1=(int)(830*(screenWidth/1024));
int toph1=(int)(35*(screenHeight/600));
int width1=(int)(60*(screenWidth/1024));
int highth1=(int)(60*(screenHeight/600));
horn=new ImageView(this);
if(sounddrawable!= null) {
soundbitmap.recycle();
sounddrawable= null;
}
soundbitmap=BitmapFactory.decodeStream(getResources().openRawResource( R.drawable.horn));
sounddrawable = new BitmapDrawable(soundbitmap);
horn.setBackgroundDrawable(sounddrawable);
RelativeLayout.LayoutParams hn=new RelativeLayout.LayoutParams(width1,highth1);
hn.setMargins(lefth1,toph1,0,0);
relativeLayout.addView(horn,hn);
horn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if(mediay2==null)
{
mediay2 = MediaPlayer.create(DesignofatozActivity.this, R.raw.hwprepsheets);
}
mediay2.start();
if(mediay2!=null)
{
}
}
});
ImageView next=(ImageView)findViewById(R.id.imv1a);
if(fwddrwable!= null) {
fwdbitmap.recycle();
fwddrwable= null;
}
fwdbitmap=BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.next_50));
fwddrwable = new BitmapDrawable(fwdbitmap);
next.setBackgroundDrawable(fwddrwable);
RelativeLayout.LayoutParams layoutnxt= (RelativeLayout.LayoutParams) next.getLayoutParams();
layoutnxt.height=(int)(30*(screenHeight/600));
layoutnxt.width=(int)(50*(screenWidth/1024));
next.setOnClickListener(new OnClickListener() {
// #Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.i("next","next");
Intent i =new Intent(DesignofatozActivity.this,Dots.class);
startActivity(i);
}
});
ImageView back=(ImageView)findViewById(R.id.back);
if(backdrwable!= null) {
backbitmap.recycle();
backdrwable= null;
}
backbitmap=BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.back1_50));
backdrwable = new BitmapDrawable(backbitmap);
back.setBackgroundDrawable(backdrwable);
RelativeLayout.LayoutParams layoutbak= (RelativeLayout.LayoutParams) back.getLayoutParams();
layoutbak.height=(int)(30*(screenHeight/600));
layoutbak.width=(int)(50*(screenWidth/1024));
back.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent i =new Intent(DesignofatozActivity.this,Slantlines.class);
startActivity(i);
}
});
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
//mPaint.setColor(0xFFFF0000);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(6);
}
private void setNoTitle() {
// TODO Auto-generated method stub
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
private Paint mPaint;
private Bitmap mBitmap;
public void colorChanged(int color) {
mPaint.setColor(color);
}
public class MyView extends View
{
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mBitmap != null) {
mBitmap.recycle();
mBitmap=null;
}
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mCanvas.setBitmap(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
if(action)
{
invalidate();
}
Paint painto = new Paint();
painto.setAntiAlias(true);
painto.setStrokeWidth(3);
painto.setStyle(Paint.Style.FILL);
int leftx1=(int)(15*(screenWidth/1024));
int leftx2=(int)(1010*(screenWidth/1024));
int topy1=(int)(60*(screenHeight/600));
int topy2=(int)(530*(screenHeight/600));
canvas.drawLine(leftx1, topy1, leftx2, topy1, painto);
canvas.drawLine(leftx1, topy1, leftx1, topy2, painto);
canvas.drawLine(15, topy2, leftx2, topy2, painto);
canvas.drawLine(leftx2, topy1, leftx2, topy2, painto);
bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.circles1_4);
int leftorg=(int)(150*(screenWidth/1024));
int toporg=(int)(110*(screenHeight/600));
canvas.drawBitmap(bitmapOrg, leftorg, toporg, painto);
bitmapOrg.recycle();
bitmapOrg=null;
bitmapOrg1 = BitmapFactory.decodeResource(getResources(),
R.drawable.circles1_5);
int leftorg1=(int)(430*(screenWidth/1024));
int toporg1=(int)(130*(screenHeight/600));
canvas.drawBitmap(bitmapOrg1, leftorg1,toporg1, painto);
bitmapOrg1.recycle();
bitmapOrg1=null;
bitmapOrg2 = BitmapFactory.decodeResource(getResources(),
R.drawable.circles1_6);
int leftorg2=(int)(650*(screenWidth/1024));
canvas.drawBitmap(bitmapOrg2, leftorg2,toporg, painto);
bitmapOrg2.recycle();
bitmapOrg2=null;
bitmapOrg3 = BitmapFactory.decodeResource(getResources(),
R.drawable.circles1_1);
int leftorg3=(int)(170*(screenWidth/1024));
int toporg3=(int)(350*(screenHeight/600));
canvas.drawBitmap(bitmapOrg3, leftorg3,toporg3, painto);
bitmapOrg3.recycle();
bitmapOrg3=null;
bitmapOrg4 = BitmapFactory.decodeResource(getResources(),
R.drawable.circles1_3);
int leftorg4=(int)(680*(screenWidth/1024));
canvas.drawBitmap(bitmapOrg4, leftorg4,toporg3, painto);
bitmapOrg4.recycle();
bitmapOrg4=null;
bitmapOrg5 = BitmapFactory.decodeResource(getResources(),
R.drawable.circles1_2);
int leftorg5=(int)(400*(screenWidth/1024));
int toporg5=(int)(300*(screenHeight/600));
canvas.drawBitmap(bitmapOrg5, leftorg5,toporg5, painto);
bitmapOrg5.recycle();
bitmapOrg5=null;
Paint paint1 = new Paint();
paint1.setAntiAlias(true);
paint1.setColor(Color.BLACK);
paint1.setStrokeWidth(3);
paint1.setStyle(Paint.Style.FILL);
paint1.setTextSize(13);
canvas.drawText("Get ready to write place your pen on the dot and follow direction ", 120, 20, paint1);
canvas.drawText("indicated by the arrow . ", 120, 38, paint1);
Paint p = new Paint();
p.setAntiAlias(true);
p.setTextSize(120);
p.setColor(Color.LTGRAY);
Typeface font = Typeface.createFromAsset(getAssets(), "font/KINDTRG.TTF");
p.setTypeface(font);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
} private float mX, mY;
private final float TOUCH_TOLERANCE = 2;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
public void clearAllResources() {
// Set related variables null
System.gc();
Runtime.getRuntime().gc();
}
#Override
protected void onPause() {
if (mediay2 != null){
mediay2.stop();
mediay2.release();
mediay2=null;
}
clearAllResources();
super.onPause();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.gc();
Runtime.getRuntime().gc();
unbindDrawables(findViewById(R.id.relative));
}
private void unbindDrawables(View view) {
// TODO Auto-generated method stub
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
}
You use memory heap more than gcc allowed size. You must use slaced bitmaps
or
+3.0 in manifest add application
android:largeHeap="true" to allocate more heap size.
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:largeHeap="true">...
Try This
After you get bitmap then recycle bitmap after use this will solve some issue.
Bitmap finalImage;
finalImage.recycle();
Or try in onResume()
System.gc();
I suggest you have a look at this thread: Strange out of memory issue while loading an image to a Bitmap object
This was answer on the thread:
public Bitmap readAssetsBitmap(String filename) throws IOException {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeStream(assets.open(filename), null, options);
if(bitmap == null) {
throw new IOException("File cannot be opened: It's value is null");
}
else {
return bitmap;
}
} catch (IOException e) {
throw new IOException("File cannot be opened: " + e.getMessage());
}
}
Remember to recycle bitmaps and set them to null once they have been used to ensure the get GCed.
Note: You shouldn't call System.gc();
I hope this helps.

Surfaceview flickering

I have a problem with the flickering.
Here is my code.
public class Tutorial2D3 extends Activity {
Panel panel;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
panel = new Panel(this);
setContentView(panel);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(1, 1, 1, "Clean Canvas");
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
panel.cleanCanvas();
return true;
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
TutorialThread thread;
Bitmap icon;
int iconWidth;
int iconHeight;
int touchX;
int touchY;
int mCount = 0;
public Panel(Context context) {
super(context);
icon = BitmapFactory
.decodeResource(getResources(), R.drawable.icon);
iconWidth = icon.getWidth();
iconHeight = icon.getHeight();
getHolder().addCallback(this);
thread = new TutorialThread(getHolder(), this);
setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
int x = touchX - (iconWidth / 2);
int y = touchY - (iconHeight / 2);
if(mCount>0) {
canvas.drawColor(Color.BLACK);
mCount--;
}
canvas.drawBitmap(icon, (x > 0 ? x : 0), (y > 0 ? y : 0), null);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
thread.setRunning(false);
do {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (retry);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchX = (int) event.getX();
touchY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
touchX = (int) event.getX();
touchY = (int) event.getY();
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return true;
}
private void cleanCanvas() {
mCount = 2;
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
The drawn image flickers.
It looks like the bitmap that is drawn at one point is drawn on one surface and not the other so it looks like flickering, the bitmap that is drawn when we touch action_up is done, that is a solid image and does not flickers. Could someone please help me with this one.
Thanks
When you are drawing in the Canvas of a SurfaceView, you must always draw every pixel of the surface.
Here you are not always clearing the Canvas in onDraw(), hence the flickering.
One thing you could do to mitigate that (and to kinda contradict Guillaume :)) is to use surfaceholder.lockCanvas(rectangle), where it is only the specified rectangle part of the canvas which is then drawn (but you must draw every pixel of that rect). Here it is, ripped from the LunarLandar sample:
#Override
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(Rectangle);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) updatePhysics();
doDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
I didn't read through all of your code, but I think this article will help.
The essence of the article is that flickering is due to double buffering and can be eliminated by drawing not to the argument Canvas but to a bitmap used as the canvas and then drawing that bitmap to the arg Canvas:
int myCanvas_w, myCanvas_h;
Bitmap myCanvasBitmap = null;
Canvas myCanvas = null;
Matrix identityMatrix;
#Override
public void surfaceCreated(SurfaceHolder holder) {
myCanvas_w = getWidth();
myCanvas_h = getHeight();
myCanvasBitmap = Bitmap.createBitmap(myCanvas_w, myCanvas_h, Bitmap.Config.ARGB_8888);
myCanvas = new Canvas();
myCanvas.setBitmap(myCanvasBitmap);
identityMatrix = new Matrix();
}
#Override
protected void onDraw(Canvas canvas) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
//int w = myCanvas.getWidth();
//int h = myCanvas.getHeight();
int x = random.nextInt(myCanvas_w-1);
int y = random.nextInt(myCanvas_h-1);
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
myCanvas.drawPoint(x, y, paint); // <--------- Here's where you draw on your bitmap
canvas.drawBitmap(myCanvasBitmap, identityMatrix, null);
// ^---------- And here's where you draw that bitmap to the canvas
}

Categories

Resources