I have got images which I want to slice into 10 pieces vertically of equal height so on hdpi slice dimensions are 800*48 (landscape application). I have got following code which is not working
public void convertBitmapinSlices(){
Bitmap tempBitmap;
try{
Paint paint = new Paint();
paint.setFilterBitmap(true);
tempBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
int targetWidth = (int) Methods.dpToPx(tempBitmap.getWidth(), this);
Log.v("TARGET_WIDTH", Integer.toString(targetWidth));
int targetHeight = (int) (Methods.dpToPx(tempBitmap.getHeight(), this)/10);
Log.v("TARGET_HEIGHT", Integer.toString(targetHeight));
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,Bitmap.Config.ARGB_8888);
RectF rectf = new RectF(0, 0, targetWidth, targetHeight);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addRect(rectf, Path.Direction.CW);
canvas.clipPath(path);
int starty=0;
lLforGardenImages.removeAllViews();
for(int i=1; i<=10;i++){
Log.v("SRC-Height", Integer.toString(targetHeight*i));
Log.v("START-Y", Integer.toString(starty));
canvas.drawBitmap(tempBitmap, new Rect(0, starty, tempBitmap.getWidth(), (tempBitmap.getHeight()/10)+starty),
new Rect(0, 0, targetWidth,targetHeight), paint);
// Matrix matrix = new Matrix();
// matrix.postScale(1f, 1f);
Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap, 0, 0, targetWidth, targetHeight, null, true);
Log.v("Width after Resizing ", resizedBitmap.getWidth()+"");
Log.v("Height after Resizing ", resizedBitmap.getHeight()+"");
BitmapDrawable bd = new BitmapDrawable(resizedBitmap);
ImageView iv = new ImageView(this);
iv.setAdjustViewBounds(true);
iv.setBackgroundDrawable(bd);
lLforGardenImages.addView(iv, llayoutParams);
if((i % 2) == 0){
iv.startAnimation(sliderAnimation(-1.0f,0.0f,0.0f,0.0f,1000));
}else{
iv.startAnimation(sliderAnimation(1.0f,0.0f,0.0f,0.0f,1000));
}
starty= starty+targetHeight;
}
}
catch(Exception e){
System.out.println("Error1 : " + e.getMessage() + e.toString());
}
}
Any idea what I am doing wrong?
Output is that slice is not correct and have contents which seems to have smaller height but height of slice is correct i.e 48 and width is correct too. So only issue with above code is that contents height seems to be incorrect even though slice height is correct.
Related
I have been working in an app that let the user takes a photo and then let him put a text over it. This is working perfect when the user types a small phrase.
This is my code:
enter code here
private Bitmap ProcessingBitmap(String captionString) {
Bitmap bm1;
Bitmap newBitmap = null;
try {
bm1 = BitmapFactory.decodeStream(getContentResolver().openInputStream(pickedImage));
//create an empty bitmap
newBitmap = Bitmap.createBitmap(bm1.getWidth(), bm1.getHeight(), Bitmap.Config.ARGB_8888);
//create a new Canvas object and pass this bitmap to it
Canvas canvas = new Canvas(newBitmap);
canvas.drawBitmap(bm1, 0, 0, null);
Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
paintText.setColor(Color.RED);
paintText.setTextSize(convertDpToPixel(50,this));
paintText.setTextAlign(Paint.Align.CENTER);
paintText.breakText(captionString,true, canvas.getWidth(),null);
paintText.setStyle(Paint.Style.FILL);
paintText.setTypeface(Typeface.create("Sans", Typeface.BOLD));
Rect textRect = new Rect();
paintText.getTextBounds(captionString, 0, captionString.length(), textRect);
if(textRect.width() >= (canvas.getWidth() - 4))
paintText.setTextSize(convertDpToPixel(25,this));
int xPos = (canvas.getWidth() / 2);
int yPos = (int) ((canvas.getHeight() / 2) - ((paintText.descent() + paintText.ascent()) / 2)) ;
//Draw Canvas
canvas.drawText(captionString, xPos, yPos, paintText);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return newBitmap;
}
However, when the user types a long phrase it goes out of the photo area!
I looked online and found a lot of information about StaticLayout. Like this one: http://ivankocijan.xyz/android-drawing-multiline-text-on-canvas/
So I tried to use it in my code but I do not know what I am doing wrong! It is not working when I use a StaticLayout Canvas.
Is there a easy way to convert this code to a staticLayout? Is there another consideration that I am missing?
I lost one week trying to solve it and nothing worked so far. Thx!
I just found a solution, it was easier than I thought! Here it goes! Hopefully it will help someone someday!
private Bitmap ProcessingBitmap(String captionString) {
Bitmap bm1;
Bitmap newBitmap = null;
try {
//Decode image
bm1 = BitmapFactory.decodeStream(getContentResolver().openInputStream(pickedImage));
//create an empty bitmap
newBitmap = Bitmap.createBitmap(bm1.getWidth(), bm1.getHeight(), Bitmap.Config.ARGB_8888);
//create a new Canvas object and pass this bitmap to it
Canvas canvas = new Canvas(newBitmap);
//pass bitmap to canvas
canvas.drawBitmap(bm1, 0, 0, null);
//Create and configure text
TextPaint mTextPaint = new TextPaint();
mTextPaint.setColor(Color.RED);
mTextPaint.setTextSize(convertDpToPixel(100,this));
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setAntiAlias(true);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setTypeface(Typeface.create("Sans", Typeface.BOLD));
//StaticLayout
StaticLayout layout = new StaticLayout(captionString, mTextPaint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1, 1, true);
//Draw Canvas
int xPos = (canvas.getWidth() / 2);
int yPos = (int) ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)) ;
canvas.translate(xPos, yPos);
//Draw Canvas
layout.draw(canvas);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return newBitmap;
}
Does anyone have a hint or explanation for the following problem ?
I draw a path with a bitmapshader. When canvas is not scaled, it looks good ( first picture ).
When I scale into ( zooming in ) the bitmapshader is not be scaled and looks very ugly. I tried several things with recreating the bitmapshader after zooming in, but did not succeed :-(. Does anyone have a hint ?
No Scaling it looks good :
when scaling it looks ugly:
Code :
canvas.scale(scalex, scaley);
canvas.translate(itranslatex, itranslatey);
fillBMP = makePatternCross(fscalex, 1, Color.GREEN/*,fscalex,fscaley*/);
fillBMPshader = new BitmapShader(fillBMP, BitmapShader.TileMode.REPEAT, BitmapShader.TileMode.REPEAT);
paintshader = new Paint();
paintshader.setShader(fillBMPshader);
canvas.drawPath(cpath.path, paintshader);
private static Bitmap makePatternCross(float fSize, float fStrokewith,int iColor) {
Log.v("Create Patter makePatternCross","makePatternCross");
float fBitmapSizeOrig = 10;
fBitmapSizeOrig=fBitmapSizeOrig*fSize;
Bitmap bm = Bitmap.createBitmap((int)fBitmapSizeOrig,(int) fBitmapSizeOrig,Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
//c.scale(200, 200);
c.drawColor(Color.WHITE);
Paint p = new Paint();
p.setColor(iColor);
//p.setStrokeWidth(iStrokewith);
p.setStrokeWidth(fStrokewith/fSize);
p.setStrokeWidth((float) 0.000001);
c.drawLine(0, 0, fBitmapSizeOrig, fBitmapSizeOrig, p);
c.drawLine(0, fBitmapSizeOrig, fBitmapSizeOrig, 0, p);
if (fSize != 1) {
int iNewSize = (int) (( fBitmapSizeOrig) * fSize);
bm = Bitmap.createScaledBitmap(bm, iNewSize, iNewSize, false);
}
int width = bm.getWidth();
int height = bm.getHeight();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (bm.getPixel(x, y) == Color.WHITE) {
bm.setPixel(x, y, Color.TRANSPARENT);
} else {
// bm.setPixel(x, y, bm.getPixel(x, y));
}
}
}
return bm;
}
Not sure exactly if this is what your looking for. But if you use a matrix to scale the bitmap it retains more quality than normal scaling.
Matrix matrix = new Matrix();
matrix.postScale(desiredScale, desiredScale);
Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0, sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
Also when going from a lesser resolution to a higher you can try this as well:
Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap source = BitmapFactory.decodeResource(a.getResources(), path, options);
I have read those posts on this issue but my case is abit different as I am NOT DISPLAYING the bitmap but just post-processing the image from raw data.
First, I call ImageProcessing.rgbToBitmap(data,width, height); which will return a Bitmap object. Then I perform these 3 functions SEPARATELY.
Rotate Bitmap
Add a watermark overlay to Bitmap
Add date at lower right hand corner of Bitmap
All 3 methods called will create an return a Bitmap object which probably causes the crash as I am trying to save an image every 1000ms! Sometimes the images saved are distorted probably due to the memory error.
I am posting my codes below and any advices are greatly appreciated. I do not want to compromise on the quality on the image taken though. (Need to preserve the resolution)
public static Bitmap addWatermark(Resources res, Bitmap source) {
int w, h;
Canvas c;
Paint paint;
Bitmap bmp, watermark;
Matrix matrix;
float scale;
RectF r;
w = source.getWidth();
h = source.getHeight();
// Create the new bitmap
bmp = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
| Paint.FILTER_BITMAP_FLAG);
// Copy the original bitmap into the new one
c = new Canvas(bmp);
c.drawBitmap(source, 0, 0, paint);
// Load the watermark
watermark = BitmapFactory.decodeResource(res, R.drawable.watermark);
// Scale the watermark to be approximately 10% of the source image
// height
scale = (float) (((float) h * 0.80) / (float) watermark.getHeight());
// Create the matrix
matrix = new Matrix();
matrix.postScale(scale, scale);
// Determine the post-scaled size of the watermark
r = new RectF(0, 0, watermark.getWidth(), watermark.getHeight());
matrix.mapRect(r);
// Center watermark
matrix.postTranslate((w - r.width()) / 2, (h - r.height()) / 2);
// Draw the watermark
c.drawBitmap(watermark, matrix, paint);
// Free up the bitmap memory
watermark.recycle();
return bmp;
}
public static Bitmap addDate(Bitmap src, String date) {
int w = src.getWidth();
int h = src.getHeight();
//Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
Bitmap result = src;
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Paint paint = new Paint();
paint.setColor(Color.rgb(255, 185, 15));
paint.setTextSize(20);
paint.setAntiAlias(true);
canvas.drawText(date, w - 200, h - 20, paint);
return result;
}
public static Bitmap rotate(Bitmap src, int rotation) {
int width = src.getWidth();
int height = src.getHeight();
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// rotate the Bitmap
matrix.postRotate(rotation);
// recreate the new Bitmap, swap width and height and apply
// transform
Bitmap rotatedBitmap = Bitmap.createBitmap(src, 0, 0, width, height,
matrix, true);
return rotatedBitmap;
}
Try this first:
Change
// Copy the original bitmap into the new one
c = new Canvas(bmp);
c.drawBitmap(source, 0, 0, paint);
with
// Copy the original bitmap into the new one
c = new Canvas(bmp);
bmp.recycle(); //here or below
c.drawBitmap(source, 0, 0, paint);
//below bmp.recycle();
and here:
canvas.drawText(date, w - 200, h - 20, paint);
return result;
with
canvas.drawText(date, w - 200, h - 20, paint);
result.recycle();
return result;
and here
Bitmap rotatedBitmap = Bitmap.createBitmap(src, 0, 0, width, height,
matrix, true);
return rotatedBitmap;
with
Bitmap rotatedBitmap = Bitmap.createBitmap(src, 0, 0, width, height,
matrix, true);
return rotatedBitmap;
rotatedBitmap.recycle();
Add all this (recycle();) maybe this is already enough and also try the code with smaller bitmaps, en see if it still crashes (like 50px by 50px).
And no, their is no way to increase the VM of your phone.
I want to Rotate Image according to a specific angle in android ,some thing like a compass...
I have this code...it works on drawPath()
but i want to replace the path and the Drawing thing with image..
I tried to create a bitmap image ,DrawBitmapImage , but the image does not Rotate like the path..Any Help PLease?
public void draw(Canvas canvas) {
double angle = calculateAngle(currentLongitude, currentLatitude, targetLongitude, targetLatitude);
//Correction;
angle-=90;
//Correction for azimuth
angle-=azimuth;
if((getContext() instanceof Activity) && ((Activity)getContext()).getWindowManager().getDefaultDisplay().getOrientation()==Configuration.ORIENTATION_PORTRAIT)angle-=90;
while(angle<0)angle=angle+360;
Rect rect = canvas.getClipBounds();
int height = rect.bottom-rect.top;
int width = rect.right-rect.left;
int left = rect.left;
int top = rect.top;
if(height>width){
top+=(height-width)/2;
height=width;
}
if(width>height){
left+=(width-height)/2;
width=height;
}
float centerwidth = width/2f;
float centerheight = height/2f;
Paint p = new Paint();
p.setColor(color);
p.setStyle(Paint.Style.FILL);
p.setAntiAlias(true);
float startX = left+(float)(centerwidth+Math.cos(deg2rad(angle))*width/3.0);
float startY = top+(float)(centerheight+Math.sin(deg2rad(angle))*height/3.0);
Path path = new Path();
path.moveTo(
startX,
startY);
path.lineTo(
left+(float)(centerwidth+Math.cos(deg2rad(angle+140))*width/4.0),
top+(float)(centerheight+Math.sin(deg2rad(angle+140))*height/4.0));
path.lineTo(
left+(float)centerwidth,
top+(float)centerheight
);
path.lineTo(
left+(float)(centerwidth+Math.cos(deg2rad(angle+220))*width/4.0),
top+(float)(centerheight+Math.sin(deg2rad(angle+220))*height/4.0)
);
path.lineTo(
startX,
startY
);
canvas.drawPath(path, p);
}
You can either rotate your bitmap when you draw it by using a matrix:
Matrix matrix = new Matrix();
matrix.setRotate(angle, imageCenterX, imageCenterY);
yourCanvas.drawBitmap(yourBitmap, matrix, null);
You can also do it by rotating the canvas before drawing:
yourCanvas.save(Canvas.MATRIX_SAVE_FLAG); //Saving the canvas and later restoring it so only this image will be rotated.
yourCanvas.rotate(-angle);
yourCanvas.drawBitmap(yourBitmap, left, top, null);
yourCanvas.restore();
Pick the one that suits you the best.
You have to rotate the canvas first and then draw whatever you want. Then the object drawn will be appeared as rotated on screen.
canvas.rotate(45); // degrees to rotate
try this its good way.
Check this tutorial you will get information about how to draw bitmap and how to rotate canvas
Check complete tutorial
This is the only one that worked for me with no problem.
private Bitmap rotateBitmap(Bitmap bitmap, int rotationAngleDegree){
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int
newW=w, newH=h;
if (rotationAngleDegree==90 || rotationAngleDegree==270){
newW = h;
newH = w;
}
Bitmap rotatedBitmap = Bitmap.createBitmap(newW,newH, bitmap.getConfig());
Canvas canvas = new Canvas(rotatedBitmap);
Rect rect = new Rect(0,0,newW, newH);
Matrix matrix = new Matrix();
float px = rect.exactCenterX();
float py = rect.exactCenterY();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotationAngleDegree);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, new Paint( Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG ));
matrix.reset();
return rotatedBitmap;
}
Based on #Sakthi 's code, but add scaling :)
Rect rect = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Matrix matrix = new Matrix();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postScale(
((float)rect.width()) / bitmap.getWidth(),
((float)rect.height()) / bitmap.getHeight());
matrix.postRotate(180);
matrix.postTranslate(rect.exactCenterX(), rect.exactCenterY());
canvas.drawBitmap(bitmap, matrix, null);
#Reham: Look at this example code below,
public class bitmaptest extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout linLayout = new LinearLayout(this);
// load the origial BitMap (500 x 500 px)
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.android);
int width = bitmapOrg.width();
int height = bitmapOrg.height();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(45);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
ImageView imageView = new ImageView(this);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);
// center the Image
imageView.setScaleType(ScaleType.CENTER);
// add ImageView to the Layout
linLayout.addView(imageView,
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT
)
);
// set LinearLayout as ContentView
setContentView(linLayout);
}
}
you have to use the matrix to rotate image look the lines
matrix.postRotate(45); -
this will rotate the image to 45 degrees
Hope this help you ...thx
Use following code. it worked for me
float rotation = 30.0f;
Bitmap bitmap = your bitmap
Rect rect = new Rect(100,100,bitmap.width, bitmap.height);
Matrix matrix = new Matrix();
float px = rect.exactCenterX();
float py = rect.exactCenterY();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotation);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, null);
matrix.reset();
invalidate();
can we set the width of a view in android?
Actually I am placing an image as background in a view.
I want to clip that image and the clipped image should fill the entire view.
I am not getting it right.can you help.
here is my code....
try{
setContentView(R.layout.main);
ImageView img = (ImageView)findViewById(R.id.img);
Paint paint = new Paint();
paint.setFilterBitmap(true);
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.puli);
int targetWidth = 300;
int targetHeight = 300;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,Bitmap.Config.ARGB_8888);
// System.out.println(" P ointsArrayX =" + PointsArrayX[i-1] + " PointsArrayY =" + PointsArrayY[i-1]);
RectF rectf = new RectF(0, 00, 100, 100);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addRect(rectf, Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap( bitmapOrg,new Rect(0, 0, bitmapOrg.getWidth(), bitmapOrg.getHeight()),
new Rect(0, 0, targetWidth, targetHeight), null);
// Matrix matrix = new Matrix();
// // resize the bit map
// matrix.postScale(100, 133);
//
// Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap, 0, 0, 100, 133, matrix, true);
// //
/*convert Bitmap to resource */
BitmapDrawable bd = new BitmapDrawable(targetBitmap);
AbsoluteLayout.LayoutParams abs_params =
new AbsoluteLayout.LayoutParams(
//width in pixels
30,
//height in pixels
40, 0, 0
);
img.setLayoutParams(abs_params);
img.setImageDrawable(bd);
img.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("onTouch");
return false;
}
});
}
catch(Exception e){
System.out.println("Error1 : " + e.getMessage() + e.toString());
}
//my main.xml is
android:layout_height="300dp"
android:layout_width="300dp"
android:id="#+id/img"
android:layout_x="10dip"
android:layout_y="50dip"
the problem is that the image is clipped and placed in the view but the clipped portion is still there. I was not able to resize the image to fit that view.Help me to solve this.Thankyou.
Add this to your xml
android:scaleType="fitXY"
Yes you can.Just put layout
android:layout_width="300dip"
set You dip as your requirement .