i used to paint the background but i want to make it drawable /picture background and the wrong in drawbackground what shall i do ?
public void surfaceCreated(SurfaceHolder arg0) {
Bitmap background = BitmapFactory.decodeResource(context.getResources(), R.drawable.download);
float scale = (float)background.getHeight()/(float)GetHeight();
int newWidth = Math.round(background.getWidth()/scale);
int newHeight = Math.round(background.getHeight()/scale);
scaled = Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
}
public void onDraw(Canvas canvas) {
canvas.drawPicture(mbgdDrawable);// draw the background
}
public void DrawBackground(Canvas canvas) {
canvas.drawBitmap(scaled, mScreenHeight, mScreenWidth,null);
}
Related
I want to draw image inside circle with bitmap and fill color outside.
I have extended AppCompatImageView and override onDraw method, but it displays white circle inside canvas.
following is my class :
class ImageMagnifier2 extends AppCompatImageView {
public ImageMagnifier2(final Context context) {
super(context);
init();
}
#Override
public boolean dispatchTouchEvent(MotionEvent me) {
// Call onTouchEvent of SimpleGestureFilterLongPress class
return super.dispatchTouchEvent(me);
}
private void init() {
setWillNotDraw(false);
setLayerType(LAYER_TYPE_HARDWARE, null);
zoomPos = new PointF(0, 0);
matrix = new Matrix();
paint = new Paint();
paintBackground = new Paint();
paint.setColor(getResources().getColor(android.R.color.transparent));
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!zooming) {
buildDrawingCache();
} else {
bitmap = getDrawingCache();
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
paint.getShader().setLocalMatrix(matrix);
paintBackground.setColor(Color.parseColor("#F227aae0"));//F227aae0
paintBackground.setStyle(Paint.Style.FILL);
paintBackground.setAntiAlias(true);
Rect rectangle = new Rect( 0, 0, canvas.getWidth(), canvas.getHeight() );
canvas.drawRect(rectangle,paintBackground);
canvas.drawCircle(zoomPos.x, zoomPos.y, sizeOfMagnifier - 5, paint);
}
}
It working fine when draw bitmap without outside rectangle or canvas fill color. but i need to fill outside color with bitmap.
Thank you for help in advance.
The following is a code the I wrote previously when I had the same issues, You may want to use the following class:
public class CircleImageView extends AppCompatImageView {
private RectF drawableRect = new RectF();
private Matrix shaderMatrix = new Matrix();
private Paint bmpPaint = new Paint();
private Paint backgroundPaint = new Paint();
private Bitmap bmp;
private int bmpWidth, bmpHeight;
private BitmapShader bmpShader;
private float radius;
public CircleImageView(Context context) {
super(context);
setScaleType(ScaleType.CENTER_CROP);
backgroundPaint.setStyle(Paint.Style.FILL);
backgroundPaint.setColor(Color.TRANSPARENT);
init();
}
#Override
protected void onDraw(Canvas canvas) {
if (bmp == null) return;
canvas.drawPaint(backgroundPaint);
canvas.drawCircle(drawableRect.centerX(), drawableRect.centerY(), radius, bmpPaint);
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) return null;
if (drawable instanceof BitmapDrawable) return ((BitmapDrawable) drawable).getBitmap();
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) bitmap = Bitmap.createBitmap(5, 5, Bitmap.Config.ARGB_8888);
else bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void initImage() {
bmp = getBitmapFromDrawable(getDrawable());
init();
}
private void init() {
if (getWidth() == 0 && getHeight() == 0) return;
if (bmp == null) {invalidate();return;}
bmpShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
bmpPaint.setAntiAlias(true);
bmpPaint.setShader(bmpShader);
bmpHeight = bmp.getHeight();
bmpWidth = bmp.getWidth();
drawableRect.set(new RectF(0,0,getWidth(),getHeight()));
radius = Math.min(drawableRect.height() / 2.0f, drawableRect.width() / 2.0f);
updateMatrix();
invalidate();
}
private void updateMatrix() {
float scale;
float dx = 0;
float dy = 0;
shaderMatrix.set(null);
if (bmpWidth * drawableRect.height() > drawableRect.width() * bmpHeight) {
scale = drawableRect.height() / (float) bmpHeight;
dx = (drawableRect.width() - bmpWidth * scale) * 0.5f;
} else {
scale = drawableRect.width() / (float) bmpWidth;
dy = (drawableRect.height() - bmpHeight * scale) * 0.5f;
}
shaderMatrix.setScale(scale, scale);
shaderMatrix.postTranslate((int) (dx + 0.5f) + drawableRect.left, (int) (dy + 0.5f) + drawableRect.top);
bmpShader.setLocalMatrix(shaderMatrix);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
init();
}
public void setBackgroundColor(#ColorInt int backgroundColor) {
backgroundPaint.setColor(backgroundColor);
invalidate();
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
initImage();
}
#Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
initImage();
}
#Override
public void setImageResource(#DrawableRes int resId) {
super.setImageResource(resId);
initImage();
}
#Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
initImage();
}
/* if this answer solved your problem please mark it as accepted by clicking the check mark next to the answer. Thank you */
}
I wrote code with guide to move my background in game and it's working, but the size of my background is original and I want to make the size of my moving background in full screen, please, help me))
Code:
public class Background extends SurfaceView implements
SurfaceHolder.Callback {
private Bitmap backGround;
public Background(Context context) {
super(context);
backGround = BitmapFactory.decodeResource(context.getResources(),
R.drawable.cold_planet);
setWillNotDraw(false);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
doDrawRunning(canvas);
invalidate();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
/**
* Draws current state of the game Canvas.
*/
private int mBGFarMoveX = 0;
private int mBGNearMoveX = 0;
private void doDrawRunning(Canvas canvas) {
// decrement the far background
mBGFarMoveX = mBGFarMoveX - 1;
// decrement the near background
mBGNearMoveX = mBGNearMoveX - 4;
// calculate the wrap factor for matching image draw
int newFarX = backGround.getWidth() - (-mBGFarMoveX);
// if we have scrolled all the way, reset to start
if (newFarX <= 0) {
mBGFarMoveX = 0;
// only need one draw
canvas.drawBitmap(backGround, mBGFarMoveX, 5000, null);
} else {
// need to draw original and wrap
canvas.drawBitmap(backGround, mBGFarMoveX, 0, null);
canvas.drawBitmap(backGround, newFarX, 0, null);
}
}
}
Example:
You should try using a transformation matrix built for ScaleToFit.CENTER. For example:
Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, b.getWidth(), b.getHeight()), new RectF(0, 0, reqWidth, reqHeight), Matrix.ScaleToFit.CENTER);
return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);
i am currently using Universal Image Loader 1.9.3 and initialize it as,
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder().displayer(new RoundedBitmapDisplayer(100)).cacheOnDisc().build();
ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(Register.this).defaultDisplayImageOptions(defaultOptions).memoryCache(new WeakMemoryCache());
ImageLoaderConfiguration config = builder.build();
imageLoader2 = ImageLoader.getInstance();
imageLoader2.init(config);
Here i have used RoundedBitmapDisplayer because i want image as round shape and i have set the property of image view in xml file as android:scaleType="centerCrop", so it must have result as center crop image but it didn't give center crop image.. images are stretched even gave center crop....
Yeah, it is mentioned that it always keep the aspect ratio, where changing scaletype property on xml wont work... use a coded crop instead
public static Bitmap toCropcenterfitoriginal(Bitmap srcBmp) {
Bitmap dstBmp = ThumbnailUtils.extractThumbnail(srcBmp,
srcBmp.getWidth() / 2, srcBmp.getWidth() / 3);
;
return dstBmp;
}
you can change the RoundedDrawable in the RoundedBitmapDisplayer with:
public static class RoundedDrawable extends Drawable {
protected final float cornerRadius;
protected final int margin;
protected RectF mRect = new RectF(),
mBitmapRect;
protected final BitmapShader bitmapShader;
protected final Paint paint;
protected Bitmap mBitmap;
public RoundedDrawable(Bitmap bitmap, int cornerRadius, int margin) {
this.cornerRadius = cornerRadius;
this.margin = margin;
mBitmap = bitmap;
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapRect = new RectF(margin, margin, bitmap.getWidth() - margin, bitmap.getHeight() - margin);
paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(bitmapShader);
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(margin, margin, bounds.width() - margin, bounds.height() - margin);
// Resize the original bitmap to fit the new bound
Matrix shaderMatrix = new Matrix();
// shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL);
int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top;
float scale = width * 1.0f / mBitmap.getWidth();
// 如果根据宽度缩放后,高度小于targetHeight
if (scale * mBitmap.getHeight() < height) {
scale = height * 1.0f / mBitmap.getHeight();
}
int outWidth = Math.round(scale * mBitmap.getWidth());
int outHeight = Math.round(scale * mBitmap.getHeight());
shaderMatrix.postScale(scale, scale);
int left = 0;
int top = 0;
if (outWidth == width) {
top = (outHeight - height) * -1 / 2;
}
else {
left = (outWidth - width) * -1 / 2;
}
shaderMatrix.postTranslate(left, top);
bitmapShader.setLocalMatrix(shaderMatrix);
}
#Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
}
then you can find your pic show in CenterCrop and rounded corner.
you can also check my github for detail: https://github.com/417704684/RoundCornerDrawable
This seems to be an open issue in Universal Image Loader. The work around that i can suggest for this is, load the image bitmap and then centercrop and corner round the bitmap as needed. Here is the code sample.
BaseActivity.imageLoader.loadImage(mUrl, mOptions, new ImageLoadingListener()
{
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason)
{
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
if (loadedImage != null)
{
Bitmap croppedBitmap = ThumbnailUtils.extractThumbnail(loadedImage, HIQUtil.dpToPixel(getActivity(), 295), HIQUtil.dpToPixel(getActivity(), 211));
Bitmap roundedCropped = getRoundedCornerBitmap(croppedBitmap, 5);
imageView.setImageBitmap(roundedCropped);
}
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
To get rounded corner bitmap, you can us this method:
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Make sure to set
adjustViewBounds ="true"
in your imageview
I newbie to Android Development, and Canvas drawings.
When I draw stuff on canvas, its easier for me to work on rectangle portion of width=height=1.
I try to scale according, but when trying to drawArc its draw it badly.
Can you please tell me what I'm doing wrong?
public class MyChart extends View{
private RectF dimentionRect;
private Paint dimentionPaint;
private static final String TAG = "VERBOSE";
public MyChart(Context context){
super(context);
initDrawingTools();
}
public MyChart(Context context,AttributeSet attrs) {
super(context,attrs);
initDrawingTools();
}
private void initDrawingTools(){
dimentionPaint = new Paint();
dimentionPaint.setColor(Color.GREEN);
dimentionPaint.setStyle(Style.FILL);
}
#Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec){
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenDimention = Math.min(widthSize, heightSize);
setMeasuredDimension(chosenDimention, chosenDimention);
Log.v(TAG, "onMeasure: "+chosenDimention);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.v(TAG, "onSizeChange");
}
#Override
public void onDraw(Canvas canvas){
float width = (float)getWidth();
Log.v(TAG, "onDraw: "+width);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(width, width);
dimentionRect = new RectF(0,0,1f,1f);
//canvas.drawRect(dimentionRect, dimentionPaint); //
canvas.drawArc(dimentionRect, 0, 180, true, dimentionPaint);
// canvas.drawCircle(0.5f, 0.5f, 0.3f, dimentionPaint);
canvas.restore();
}
}
Ok, I didn't find a solution but I was able to find a work-around for it.
I created a background bitmap and using it for a local Canvas which do the drawing stuff. after all drawings I draw the bitmap again into my canvas.
I know its not elegant but thats the solution I found
private void drawBackground(Canvas canvas){
if(background != null){
canvas.drawBitmap(background, 0,0,backgroundPaint);
Log.e(TAG, "Drawing background");
}
}
private void regenerateBackground(){
if(background != null){
background.recycle();
}
background = Bitmap.createBitmap(getWidth(), getWidth(), Config.ARGB_8888);
RectF rect = new RectF(0,0,getWidth(),getWidth());
Canvas c = new Canvas(background);
c.drawRect(rect, backgroundPaint);
}
#Override
protected void onDraw(Canvas canvas){
drawBackground(canvas);
float width = (float)getWidth();
Canvas c = new Canvas(background);
c.save(Canvas.MATRIX_SAVE_FLAG);
c.scale(width,width);
border = new RectF(0,0,1,1);
//
Paint p = new Paint();
p.setColor(Color.GREEN);
p.setStyle(Style.FILL);
c.drawArc(border, 0, 360,true, p);
c.restore();
}
Okay so Im trying to set the background of a SurfaceView to a JPG file. But it doesn't seem to want to draw the image, and all I get is a black screen.
Here:s my code:
public class FloorplanActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(getApplicationContext());
setContentView(mapView);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.floorplan, menu);
return true;
}
class MapView extends SurfaceView{
Rect testRectangle1 = new Rect(0, 0, 50, 50);
Bitmap scaled;
int x;
int y;
public MapView(Context context) {
super(context);
}
public void surfaceCreated(SurfaceHolder arg0){
Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.floorplan);
float scale = (float)background.getHeight()/(float)getHeight();
int newWidth = Math.round(background.getWidth()/scale);
int newHeight = Math.round(background.getHeight()/scale);
scaled = Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
}
public void onDraw(Canvas canvas) {
canvas.drawBitmap(scaled, 0, 0, null); // draw the background
}
Not sure why it won't draw the "floorplan" image I have saved in the drawable-mdpi folder.
Anyone got any suggestions?
Thanks.
EDIT: After doing some debugging with breakpoints, it seems like the "scaled" variable becomes "Infinity" for some reason and as such the newWidth and newHeight variables become less than 0 and the application crashes.
This is only if I move the entire surfaceCreated into the contstructor, if I leave the code as is here then it doesn't do anything beyind displaying a black screen.
No idea what's causing it to do that though...
First, you should implement SurfaceHolder.Callback interface with your MapView class and set it as a callback for its SurfaceHolder to make the app call your onSurfaceCreated() metod.
Second, if you want your onDraw() method to be called, then call setWillNotDraw(false) in your MapView's constructor.
I've done that as following:
public class MapView extends SurfaceView implements SurfaceHolder.Callback {
private Bitmap scaled;
public MapView(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
getHolder().addCallback(this);
}
public void onDraw(Canvas canvas) {
canvas.drawBitmap(scaled, 0, 0, null); // draw the background
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.dr);
float scale = (float) background.getHeight() / (float) getHeight();
int newWidth = Math.round(background.getWidth() / scale);
int newHeight = Math.round(background.getHeight() / scale);
scaled = Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Callback method contents
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Callback method contents
}
}
And it works well.
NOTE: Moved MapView class to a separate *.java file.
Update Watch Duplicate Copy Move