How to develop custom cropping rectangle in android? - android

I am developing an application where i need to crop image . But this image croping should happen on my activity only so i can not use default image cropping concept of android where image will go on another view where user can crop .
What i need is to create custom image cropper rectangle .
I am trying this from long but no luck . Would be glad if any body can help .
Thanks

my mainactivity..
public class MainActivity extends Activity {
private DragRectView view;
private ImageView original;
// private ImageView croppedImage;
/**
*
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = (DragRectView) findViewById(R.id.dragRect);
original = (ImageView) findViewById(R.id.image);
// croppedImage = (ImageView) findViewById(R.id.crop_image);
if (null != view) {
view.setOnUpCallback(new DragRectView.OnUpCallback() {
#Override
public void onRectFinished(final Rect rect) {
Toast.makeText(
getApplicationContext(),
"Rect is (" + rect.left + ", " + rect.top + ", "
+ rect.right + ", " + rect.bottom + ")",
Toast.LENGTH_LONG).show();
Bitmap bitmap1 = Bitmap.createScaledBitmap(
((BitmapDrawable) original.getDrawable())
.getBitmap(), original.getWidth(), original
.getHeight(), false);
System.out.println(rect.height() + " "
+ bitmap1.getHeight() + " " + rect.width()
+ " " + bitmap1.getWidth());
if (rect.height() <= bitmap1.getHeight()
&& rect.width() <= bitmap1.getWidth()) {
Bitmap bitmap = Bitmap.createBitmap(bitmap1,
view.getLeft(), view.getTop(), view.getWidth(),
view.getHeight());
System.out
.println("MainActivity.onCreate(...).new OnUpCallback() {...}.onRectFinished() if true");
Intent intent = new Intent(MainActivity.this,
CropImageActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("cropimage", bitmap);
startActivity(intent);
System.out.println("MainActivity.onCreate() ");
}
}
});
}
}
}
cropImageAcivity...
public class CropImageActivity extends Activity {
private ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.crop_image);
imageView = (ImageView) findViewById(R.id.crop_image);
Intent intent = getIntent();
if (intent != null) {
Bundle extras = intent.getExtras();
if (extras != null) {
System.out.println("CropImageActivity.onCreate()");
Bitmap bitmap = extras.getParcelable("cropimage");
imageView.setImageBitmap(bitmap);
}
}
}
}
DragRectangle...
public class DragRectView extends View {
private Paint mRectPaint;
private int mStartX = 0;
private int mStartY = 0;
private int mEndX = 0;
private int mEndY = 0;
private boolean mDrawRect = false;
private TextPaint mTextPaint = null;
private OnUpCallback mCallback = null;
public interface OnUpCallback {
void onRectFinished(Rect rect);
}
public DragRectView(final Context context) {
super(context);
init();
}
public DragRectView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public DragRectView(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
init();
}
/**
* Sets callback for up
*
* #param callback
* {#link OnUpCallback}
*/
public void setOnUpCallback(OnUpCallback callback) {
mCallback = callback;
}
/**
* Inits internal data
*/
private void init() {
mRectPaint = new Paint();
mRectPaint.setColor(Color.GREEN);
mRectPaint.setStyle(Paint.Style.STROKE);
mRectPaint.setStrokeWidth(5);
mTextPaint = new TextPaint();
mTextPaint.setColor(Color.MAGENTA);
mTextPaint.setTextSize(20);
}
#Override
public boolean onTouchEvent(final MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDrawRect = false;
mStartX = (int) event.getX();
mStartY = (int) event.getY();
invalidate();
break;
case MotionEvent.ACTION_MOVE:
final int x = (int) event.getX();
final int y = (int) event.getY();
if (!mDrawRect || Math.abs(x - mEndX) > 5
|| Math.abs(y - mEndY) > 5) {
mEndX = x;
mEndY = y;
invalidate();
}
mDrawRect = true;
break;
case MotionEvent.ACTION_UP:
if (mCallback != null) {
mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX),
Math.min(mStartY, mEndY), Math.max(mEndX, mStartX),
Math.max(mEndY, mStartX)));
}
invalidate();
break;
default:
break;
}
return true;
}
#Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
if (mDrawRect) {
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY),
mRectPaint);
canvas.drawText(
" (" + Math.abs(mStartX - mEndX) + ", "
+ Math.abs(mStartY - mEndY) + ")",
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY),
mTextPaint);
}
}
}
mainactvity layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/background_dark"
android:orientation="vertical"
android:weightSum="2" >
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/image" />
<com.afbb.imagecrop.DragRectView
android:id="#+id/dragRect"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!--
<ImageView
android:id="#+id/crop_image"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitXY"
android:src="#drawable/image" />
-->
</RelativeLayout>
cropactivity layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/crop_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/ic_launcher" />
</FrameLayout>
it may help you...

you can try this for flexible and custom crop.....
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setType("image/*");
intent.putExtra("aspectX", 0);
intent.putExtra("aspectY", 0);
intent.putExtra("outputY", 600);
intent.putExtra("outputX", 600);
intent.putExtra("scale", "true);

Related

Creating bitmap from area selected by touch, returns wrong image part android

I use custom view placed over an image view like that
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="5"
tools:context=".TextRecognitionActivity">
<ImageView
android:id="#+id/surfaceViewImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>
<com.gypsywaiter.app.DragRectView
android:id="#+id/dragRectView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
/>
<Button
android:id="#+id/capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:layout_weight="1"
android:text="Capture"/>
</FrameLayout>
And I draw a rectangle in this view upon user selects and drags as follow
public class DragRectView extends View {
private Paint mRectPaint;
private int mStartX = 0;
private int mStartY = 0;
private int mEndX = 0;
private int mEndY = 0;
private boolean mDrawRect = false;
private TextPaint mTextPaint = null;
private OnUpCallback mCallback = null;
public interface OnUpCallback {
void onRectFinished(Rect rect);
}
public DragRectView(final Context context) {
super(context);
init();
}
public DragRectView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public DragRectView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init();
}
/**
* Sets callback for up
*
* #param callback {#link OnUpCallback}
*/
public void setOnUpCallback(OnUpCallback callback) {
mCallback = callback;
}
/**
* Inits internal data
*/
private void init() {
mRectPaint = new Paint();
mRectPaint.setColor(getContext().getResources().getColor(android.R.color.holo_green_light));
mRectPaint.setStyle(Paint.Style.FILL);
mRectPaint.setStrokeWidth(5); // TODO: should take from resources
mRectPaint.setAlpha(60);
mTextPaint = new TextPaint();
mTextPaint.setColor(getContext().getResources().getColor(android.R.color.holo_green_light));
mTextPaint.setTextSize(20);
}
#Override
public boolean onTouchEvent(final MotionEvent event) {
// TODO: be aware of multi-touches
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDrawRect = false;
mStartX = (int) event.getX();
mStartY = (int) event.getY();
invalidate();
break;
case MotionEvent.ACTION_MOVE:
final int x = (int) event.getX();
final int y = (int) event.getY();
Log.d("logger", x + "//" + y);
//if (!mDrawRect || Math.abs(x - mEndX) > 5 || Math.abs(y - mEndY) > 5) {
mEndX = x;
mEndY = y;
invalidate();
//}
mDrawRect = true;
break;
case MotionEvent.ACTION_UP:
int[] location = new int[2];
getLocationOnScreen(location);
invalidate();
if (mCallback != null) {
mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mStartY, mEndY)));
}
break;
default:
break;
}
return true;
}
#Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), mRectPaint);
}
When I try to extract that selected part like that,
dragRectView.setOnUpCallback(new DragRectView.OnUpCallback() {
#Override
public void onRectFinished(Rect rect) {
Bitmap nBitmap = Bitmap.createBitmap(loadedImage,rect.top, rect.left , rect.bottom, rect.right);
}
});
I always get the wrong area and some times crash that x must be less than width. I think it is something related to coordinates but I can't figure it out.
The problem was in the difference between image resolution and the ImageView dimensions.
Solution is:
Resize the bitmap image to be the same width and height of the ImageView and it will work.

Drawing a abitmap based on the compass direction

What i need to do is the bitmap to be drawn at the edge outside the circle.
I'm getting it right sometimes, but it's getting wrong when I rotate the device.
I also tried the rotation Animation, but i didn't get the result I want.
Please help.
That's what's expected:
What I'm getting: for this image it's working fine
it's getting wrong here
and here:
The Code(google tutorial for compass):
CompassFragment Class:
public class CompassFragment extends Fragment implements SensorEventListener {
SensorManager sensorManager;
private Sensor sensorAccelerometer;
private Sensor sensorMagneticField;
private float[] valuesAccelerometer;
private float[] valuesMagneticField;
private float[] matrixR;
private float[] matrixI;
private float[] matrixValues;
TextView readingAzimuth, readingPitch, readingRoll;
Compass myCompass;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_compass, container, false);
readingAzimuth = (TextView) view.findViewById(R.id.azimuth);
readingPitch = (TextView) view.findViewById(R.id.pitch);
readingRoll = (TextView) view.findViewById(R.id.roll);
myCompass = (Compass) view.findViewById(R.id.mycompass);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMagneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
valuesAccelerometer = new float[3];
valuesMagneticField = new float[3];
matrixR = new float[9];
matrixI = new float[9];
matrixValues = new float[3];
}
#Override
public void onResume() {
sensorManager.registerListener(this,
sensorAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this,
sensorMagneticField,
SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
#Override
public void onPause() {
sensorManager.unregisterListener(this,
sensorAccelerometer);
sensorManager.unregisterListener(this,
sensorMagneticField);
super.onPause();
}
#Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
for (int i = 0; i < 3; i++) {
valuesAccelerometer[i] = event.values[i];
}
break;
case Sensor.TYPE_MAGNETIC_FIELD:
for (int i = 0; i < 3; i++) {
valuesMagneticField[i] = event.values[i];
}
break;
}
boolean success = SensorManager.getRotationMatrix(
matrixR,
matrixI,
valuesAccelerometer,
valuesMagneticField);
if (success) {
SensorManager.getOrientation(matrixR, matrixValues);
double azimuth = Math.toDegrees(matrixValues[0]);
double pitch = Math.toDegrees(matrixValues[1]);
double roll = Math.toDegrees(matrixValues[2]);
readingAzimuth.setText("Azimuth: " + String.valueOf(azimuth));
readingPitch.setText("Pitch: " + String.valueOf(pitch));
readingRoll.setText("Roll: " + String.valueOf(roll));
myCompass.update(matrixValues[0]);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
Compass Class:
public class Compass extends View {
private Bitmap bitmap;
private float direction;
private HashMap<String, Bitmap> mStore = new HashMap<String, Bitmap>();
private Context context;
private int h, w, r;
private Paint paint;
private Canvas canvas;
public Compass(Context context) {
super(context);
// TODO Auto-generated constructor stub
this.context = context;
}
public Compass(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public Compass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-ge
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(
MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
#Override
protected void onDraw(Canvas canvas) {
w = getMeasuredWidth();
h = getMeasuredHeight();
r = 0;
if (w > h) {
r = h / 2;
} else {
r = w / 2;
}
paint = new Paint();
// Paint.ANTI_ALIAS_FLAG
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
canvas.drawCircle(w / 2, h / 2, r, paint);
paint.setColor(Color.RED);
drawImage1(canvas);
}
private void drawImage1(Canvas canvas) {
BitmapFactory.Options myOptions = new BitmapFactory.Options();
myOptions.inDither = true;
myOptions.inScaled = false;
myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
myOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher, myOptions);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
Bitmap workingBitmap = Bitmap.createBitmap(bitmap);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
float left = (float) ((w / 2 + r * Math.sin(-direction)));
float top = (float) (h / 2 - r * Math.cos(-direction));
Log.e("cords", left + " " + top);
canvas.drawBitmap(mutableBitmap, left, top, paint);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/azimuth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/mainColor" />
<TextView
android:id="#+id/pitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/mainColor" />
<TextView
android:id="#+id/roll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/mainColor" />
</LinearLayout>
<com.example.compass.Compass
android:id="#+id/mycompass"
class="com.nilecode.Compass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
</com.example.compass.Compass>
</LinearLayout>

Drawline on canvas does not follow my fingers touch

I try to draw on ImageView from a file resource. Here is my code:
private Bitmap myBitmap;
private Bitmap mutableBitmap;
private Canvas canvas;
private Paint paint;
private ImageView img;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.layout_imagefullscreen);
paint = new Paint();
paint.setStrokeWidth(11);
paint.setColor(Color.YELLOW);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);
...
if (imageFileFullPathName != null) {
try {
File imgFile = new File (imageFileFullPathName);
if (imgFile.exists ()) {
myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
mutableBitmap = myBitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(mutableBitmap);
img.setImageBitmap(mutableBitmap);
Matrix m = img.getImageMatrix();
canvas.setMatrix(m);
}
} catch (Exception e) {
e.printStackTrace ();
}
}
img.setOnTouchListener (new OnTouchListener() {
float startX, startY;
float stopX, stopY;
#Override
public boolean onTouch (View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
Log.i("---> DOWN X", String.valueOf(startX));
Log.i("---> DOWN Y", String.valueOf(startY));
break;
case MotionEvent.ACTION_MOVE:
stopX = event.getRawX();
stopY = event.getRawY();
Log.i("---> MOVE X", String.valueOf(stopX));
Log.i("---> MOVE Y", String.valueOf(stopY));
canvas.drawLine(startX, startY, stopX, stopY, paint);
img.invalidate();
startX = event.getRawX();
startY = event.getRawY();
img.setImageBitmap(mutableBitmap);
break;
case MotionEvent.ACTION_UP:
stopX = event.getRawX();
stopY = event.getRawY();
Log.i("---> UP X", String.valueOf(stopX));
Log.i("---> UP Y", String.valueOf(stopY));
canvas.drawLine(startX, startY, stopX, stopY, paint);
img.invalidate();
break;
default:
break;
}
v.performClick();
return true;
}
});
}
}'
But when I move my finger on the ImageView, the line does not follow my finger, it limits only on the top left of the screen instead. I also try to change getRawX() to getX(), but this issue persists. I believe the problem is something about coordinates transformation, but could not figure how to solve it. Please help, thanks!
Layout xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#color/Black">
<ImageView
android:id="#+id/imagefullscreenview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/ic_launcher"/>
</LinearLayout>
From your code, it looks like you are trying to drawing following the touched finger. So here is how you draw...
public class MainActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, OnTouchListener {
SurfaceView sv;
SurfaceHolder sh;
RenderingThread thread;
Canvas canvas = null;
int Width = 0, Height = 0;
Button btnClear;
Path path = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
try{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
sv = (SurfaceView)findViewById(R.id.sv);
sv.setOnTouchListener(this);
btnClear = (Button)findViewById(R.id.btnClear);
path = new Path();
sh = sv.getHolder();
if(sh != null)
{
sh.addCallback(this);
}
else
{
Toast.makeText(getApplicationContext(), "Failed to initialize", Toast.LENGTH_SHORT).show();
finish();
}
}catch(Throwable ex)
{
ex.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed to start", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
try{
Width = width;
Height = height;
thread = new RenderingThread(holder, width, height);
canvas = new Canvas(thread.drawingBitmap);
thread.start();
}catch(Throwable ex) {
ex.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed to initialize", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
sv.setWillNotDraw(false);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.RequestStop();
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getRawX(), event.getRawY());
break;
case MotionEvent.ACTION_MOVE:
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5);
CornerPathEffect pathEffect = new CornerPathEffect(45);
paint.setPathEffect(pathEffect);
path.lineTo(event.getRawX(), event.getRawY());
canvas.drawPath(path, paint);
//
Log.i("minor",""+event.getTouchMinor());
Log.i("major",""+event.getTouchMajor());
break;
case MotionEvent.ACTION_UP:
path.reset();
break;
}
return true;
}
#Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.btnClear:
canvas.drawColor(Color.WHITE);
break;
}
}
}
Here btnClear is a button in XML from which you can clear the canvas.
Here is the XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<SurfaceView
android:id="#+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/btnClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear"
android:textSize="18sp"
android:textColor="#ffffff"
android:background="#555555"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:onClick="onClick" />
</RelativeLayout>
And here is the rendering thread...
public class RenderingThread extends Thread {
private boolean keepRunning = true;
private SurfaceHolder holder = null;
public Bitmap drawingBitmap = null;
private int width = 0, height = 0;
public RenderingThread(SurfaceHolder holder, int width, int height)
{
this.holder = holder;
this.width = width;
this.height = height;
drawingBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
}
public void RequestStop()
{
keepRunning = false;
interrupt();
}
#Override
public void run() {
while(keepRunning)
{
try{
Thread.sleep(30);
//
if(holder != null && drawingBitmap != null)
{
Canvas canvas = holder.lockCanvas();
if(canvas != null)
{
canvas.drawColor(Color.WHITE);
Rect src = new Rect(0, 0, drawingBitmap.getWidth(), drawingBitmap.getHeight());
Rect dst = new Rect(0, 0, width, height);
canvas.drawBitmap(drawingBitmap, src, dst, new Paint());
//
holder.unlockCanvasAndPost(canvas);
}
}
}catch(Throwable ex) {
ex.printStackTrace();
}
}
}
}
Good Luck. :)

Change text color and background color of textview using color picker in android

How to change text color and background color of TextView using color picker in android.
To Add note which have functionality to change color of text and background choosing color form the color picker.
download this project import it.Color-picker
right click on project ---> property ---> android --->Add Click and add download project.
Create new Project
layout
Note : use the image of color picker from downloaded project res folder---> drawable
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<EditText
android:id="#+id/txNote"
android:layout_width="200dip"
android:layout_height="200dip"
android:layout_centerInParent="true"
android:text="#string/hello_world" />
<ImageView
android:id="#+id/rightColorPicker"
android:layout_width="#dimen/ambilwarna_hueWidth"
android:layout_height="#dimen/ambilwarna_hsvHeight"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/txNote"
android:scaleType="fitXY"
android:src="#drawable/ambilwarna_hue" />
<ImageView
android:id="#+id/leftColorPicker"
android:layout_width="#dimen/ambilwarna_hueWidth"
android:layout_height="#dimen/ambilwarna_hsvHeight"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/txNote"
android:scaleType="fitXY"
android:src="#drawable/ambilwarna_hue" />
</RelativeLayout>
Activity
public class MainActivity extends Activity implements OnTouchListener {
TextView txtNote;
ImageView rightColorPicker,leftColorPicker;
private int mAppWidgetId = 0 ;
public static boolean flag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtNote=(TextView)findViewById(R.id.txNote);
rightColorPicker=(ImageView)findViewById(R.id.rightColorPicker);
leftColorPicker=(ImageView)findViewById(R.id.leftColorPicker);
rightColorPicker.setOnTouchListener(this);
leftColorPicker.setOnTouchListener(this);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
case R.id.rightColorPicker:
colorPicker();
flag=true;
break;
case R.id.leftColorPicker:
colorPicker();
flag=false;
break;
default:
break;
}
return false;
}
public void colorPicker() {
// initialColor is the initially-selected color to be shown in the rectangle on the left of the arrow.
// for example, 0xff000000 is black, 0xff0000ff is blue. Please be aware of the initial 0xff which is the alpha.
ColorPickerDialog dialog = new ColorPickerDialog(this, 0xff0000ff, new OnAmbilWarnaListener() {
// Executes, when user click Cancel button
#Override
public void onCancel(ColorPickerDialog dialog){
}
// Executes, when user click OK button
#Override
public void onOk(ColorPickerDialog dialog, int color) {
// Create an Intent to launch WidgetConfigurationActivity screen
Intent intent = new Intent(getBaseContext(), MainActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
// This is needed to make this intent different from its previous intents
intent.setData(Uri.parse("tel:/"+ (int)System.currentTimeMillis()));
// Creating a pending intent, which will be invoked when the user
// clicks on the widget
PendingIntent pendingIntent = PendingIntent.getActivity(getBaseContext(), 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Getting an instance of WidgetManager
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getBaseContext());
if (flag) {
txtNote.setBackgroundColor(color);
} else {
txtNote.setTextColor(color);
}
// // Instantiating the class RemoteViews with widget_layout
RemoteViews views = new
RemoteViews(getBaseContext().getPackageName(), R.layout.activity_main);
//
// // Setting the background color of the widget
views.setInt(R.id.txNote, "setBackgroundColor", color);
//
// // Attach an on-click listener to the clock
views.setOnClickPendingIntent(R.id.txNote,pendingIntent);
// Tell the AppWidgetManager to perform an update on the app widget
appWidgetManager.updateAppWidget(mAppWidgetId, views);
// Return RESULT_OK from this activity
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
//finish();
}
});
dialog.show();
}
}
You can use the below for reference. It may not be exactly as snap shot posted in your question. You can use the below and modify it according to your requirements.
When you click the button color picker dialog pops up. You can select the color and click the center circle. The textview text color changes to the color choosen.
public class MainActivity extends Activity implements ColorPickerDialog.OnColorChangedListener {
Button b1;
TextView tv;
Paint mPaint;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPaint = new Paint();
tv = (TextView) findViewById(R.id.tv);
b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new ColorPickerDialog(MainActivity.this, MainActivity.this, mPaint.getColor()).show();
}
});
}
#Override
public void colorChanged(int color) {
// TODO Auto-generated method stub
tv.setTextColor(color);
}
}
Color Picker
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");
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv"
android:layout_above="#+id/button1"
android:layout_alignRight="#+id/button1"
android:layout_marginBottom="180dp"
android:text="#string/hello_world" />
</RelativeLayout>
You can also use a color picker from https://code.google.com/p/android-color-picker/
activity
As is replied in this question: Android Color Picker there is an example of color picker. Using it you could change the color with:
Color colorPicket = Color.parse("color returned of color picket");
TextView textView = (TextView) v;
textView.setBackgroundColor(colorPicked); //if it returns in hex you can parse with COlor.par
textView.setTextColor(colorPicked);
Take a look: Color.parseColor
I don't know how you get your colors from the picker, so I suppose that you get it as a triplet of RGB colors/hexadecimal. Then you have to use the method setTextColor(int color) There are many possibilities :
myTextView.setTextColor(Color.rgb(100,100,100)); //get color as a triplet RGB
myTextView.setTextColor(Color.parseColor("#FFFFFF")); //get color as hexadecimal String
To set the background of your textView, use simply the method setBackgroundColor(int color) (inherited from the View class):
myTextView.setBackgroundColor(Color.rgb(100,100,100)); //example

Android: Draw inside a frame determined by a Bitmap in an ImageView

I want to create a window where the user can go out of the borders of the image but the path continues.
I have this code for my Activity
public class PaintActivity extends Activity {
PaintView maskView;
ImageView imagen;
Bitmap bitmap;
Bitmap mask;
int bitmapWidth, bitmapHeight;
public int[] getBitmapMinCoords() {
float[] minCoordF = {0, 0};
Matrix matriz = imagen.getImageMatrix();
matriz.mapPoints(minCoordF);
int[] minCoords = new int[2];
minCoords[0] = Math.round(minCoordF[0]);
minCoords[1] = Math.round(minCoordF[1]);
return minCoords;
}
public int[] getBitmapMaxCoords() {
float[] maxCoordF = {bitmapWidth, bitmapHeight};
Matrix matriz = imagen.getImageMatrix();
matriz.mapPoints(maxCoordF);
int[] maxCoords = new int[2];
maxCoords[0] = Math.round(maxCoordF[0]);
maxCoords[1] = Math.round(maxCoordF[1]);
return maxCoords;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.paint);
imagen = (ImageView) findViewById(R.id.image_paint);
maskView = (PaintView) findViewById(R.id.mask_paint);
String imagePath = "/sdcard/images/NewOrleans.gif";
bitmap = BitmapFactory.decodeFile(imagePath);
imagen.setImageBitmap(bitmap);
bitmapWidth = bitmap.getWidth();
bitmapHeight = bitmap.getHeight();
ViewTreeObserver vto = imagen.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
Matrix matrizTransformacion = imagen.getImageMatrix();
float[] values = new float[9];
if (matrizTransformacion != null) {
matrizTransformacion.getValues(values);
Log.i(PaintActivity.class.toString() + ".globalListener()", "La matriz tiene valores: " + matrizTransformacion.toString() );
}
int[] minC = getBitmapMinCoords();
int[] maxC = getBitmapMaxCoords();
Log.i("Listener MinCOORDS (0,0)", minC[0] + ", " + minC[1]);
Log.i("Listener MaxCOORDS (" + bitmapWidth + "," + bitmapHeight + ")", maxC[0] + ", " + maxC[1]);
Bitmap mapaBits = Bitmap.createBitmap( bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mapaBits);
maskView.layout(minC[0], minC[1], maxC[0], maxC[1]);
maskView.draw(canvas);
maskView.refreshDrawableState();
imagen.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
Bitmap getMaskBitmap(View view) {
Matrix matrizTransformacion = imagen.getImageMatrix();
float[] values = new float[9];
if (matrizTransformacion != null) {
matrizTransformacion.getValues(values);
Log.i(PaintActivity.class.toString() + ".onStart()", "La matriz tiene valores: " + matrizTransformacion.toString() );
}
Bitmap mapaBits = Bitmap.createBitmap( Math.round(bitmapWidth*values[0]), Math.round(bitmapHeight*values[4]), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mapaBits);
int[] minCoords = getBitmapMinCoords();
int[] maxCoords = getBitmapMaxCoords();
view.layout(minCoords[0], minCoords[1], maxCoords[0], maxCoords[1]);
view.draw(canvas);
return mapaBits;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.inpainting_color_selection_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.inpainting_color_accept_opt:
ProgressDialog pd = ProgressDialog.show(this, "", "Guardando imagen");
Bitmap mascara = getMaskBitmap(maskView);
// GUARDANDO BITMAP EN HDD
try {
String filename = "/sdcard/PhotoRestore/mask.png";
File file = new File(filename);
FileOutputStream out = new FileOutputStream(file);
mascara.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
}
pd.dismiss();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
This is the code for my PaintView
public class PaintView extends View {
float previousX = -1;
float previousY = -1;
float currentX = -1;
float currentY = -1;
PaintActivity activity;
Path path;
Paint paintLine = new Paint();
public PaintView(Context context) {
super(context);
init();
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PaintView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
path = new Path();
activity = (PaintActivity) getContext();
paintLine = new Paint(Paint.ANTI_ALIAS_FLAG);
paintLine.setStyle(Paint.Style.STROKE);
paintLine.setStrokeWidth(10);
paintLine.setColor(Color.GREEN);
paintLine.setAlpha(150);
}
public void onDraw(Canvas canvas) {
canvas.drawPath(path, paintLine);
}
#Override
public boolean onTouchEvent(final MotionEvent event) {
currentX = event.getX();
currentY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(currentX, currentY);
break;
case MotionEvent.ACTION_MOVE:
path.quadTo(previousX, previousY, currentX, currentY);
break;
case MotionEvent.ACTION_UP:
path.quadTo(previousX, previousY, currentX, currentY);
break;
}
previousX = currentX;
previousY = currentY;
postInvalidate();
return true;
}
}
And this is my XML view
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/image_paint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/hola" />
<com.paint.PaintView
android:id="#+id/mask_paint"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
When I push the button I added in the menu I save the image inside memory and the screen continues being there but now i've got a border. Far away this border the paths continues drawing but it's occluded under a black surface and paths are not cutted, that's I want to occur at the beginning of the activity.
I tried to do the same in the 'onCreate()' method of the activity (inside the global layout listener) but it don't runs.
Someone could help me?
First of all, lost of thanks!
I found the way to solve my problem.
Where I need to put the view.layout() is inside the onDraw() method of the view that I want to be layout resized.

Categories

Resources