如何在底部的图像位图上放置文本?
how to put text on image bitmap at bottom?
我想要的:我想在我从图库或相机中选择的图像底部添加文本。
原图
我在底部的图像中添加了蓝色色带
在那个条带中,我想恰好在中间添加一些文本。
问题是什么:
- 我无法将文本准确定位在蓝色色带的中间。
- 对于不同的图片,文字大小会发生变化。有的时候很小,有的时候很大。
我试过的:我的代码如下。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageView);
}
public void openGallery(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 100);
}
public void openCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 101);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && resultCode == Activity.RESULT_OK) {
if (requestCode == 100) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media
.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
addStampToImage(bitmap);
} else if (requestCode == 101) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
addStampToImage(bitmap);
}
}
}
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
Paint pText = new Paint();
pText.setColor(Color.WHITE);
pText.setTextSize((int) (20 * scale));
String text = "Maulik";
/*Rect r = new Rect();
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
pText.setTextAlign(Paint.Align.LEFT);
pText.getTextBounds(text, 0, text.length(), r);
float x = -r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
int minusSpace = (int) (canvas.getClipBounds().bottom * 0.07);
canvas.drawText(text, 0, canvas.getClipBounds().bottom - minusSpace, pText);*/
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
int x = (newBitmap.getWidth() - bounds.width())/6;
int y = (newBitmap.getHeight() + bounds.height())/5;
canvas.drawText(text, x * scale, y * scale, pText);
mImageView.setImageBitmap(newBitmap);
}
}
任何帮助将不胜感激!
更新时间:2018 年 8 月 1 日
addStampToImage 方法中的更改。
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Rect textHeightWidth = new Rect();
pText.getTextBounds(fromWhichMode, 0, fromWhichMode.length(), textHeightWidth);
canvas.drawText(textToStamp, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
pText);
以上更改使我在蓝色条带中间显示了文本。但核心 ISSUE 保持不变。即文本大小会根据不同的图像大小而变化。
试试这个我觉得对你有帮助
/**
* 对于水印
*/
public static Bitmap waterMark(Bitmap src, String watermark, Point location, int color, int alpha, int size, boolean underline) {
int[] pixels = new int[100];
//get source image width and height
int widthSreen = src.getWidth(); // 1080L // 1920
int heightScreen = src.getHeight(); // 1343L // 2387
Bitmap result = Bitmap.createBitmap(widthSreen, heightScreen, src.getConfig());
//create canvas object
Canvas canvas = new Canvas(result);
//draw bitmap on canvas
canvas.drawBitmap(src, 0, 0, null);
//create paint object
Paint paint = new Paint();
// //apply color
// paint.setColor(color);
// //set transparency
// paint.setAlpha(alpha);
// //set text size
size = ((widthSreen * 5) / 100);
paint.setTextSize(size);
// paint.setAntiAlias(true);
// //set should be underlined or not
// paint.setUnderlineText(underline);
//
// //draw text on given location
// //canvas.drawText(watermark, w / 4, h / 2, paint);
Paint.FontMetrics fm = new Paint.FontMetrics();
paint.setColor(Color.WHITE);
// paint.setTextSize(18.0f);
paint.getFontMetrics(fm);
int margin = 5;
canvas.drawRect(50 - margin, 50 + fm.top - margin,
50 + paint.measureText(watermark) + margin, 50 + fm.bottom
+ margin, paint);
paint.setColor(Color.RED);
canvas.drawText(watermark, 50, 50, paint);
return result;
}
在您的 onActivityResult 上调用此方法
Bitmap bitmapp = waterMark(bitmap, your_string, p, Color.RED, 90, 90, true);
检查以下代码:-
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
String text = "Maulik";
Paint pText = new Paint();
pText.setColor(Color.WHITE);
setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
int x= ((newBitmap.getWidth()-(int)pText.measureText(text))/2);
int h=(extraHeight+bounds.height())/2;
int y=(originalBitmap.getHeight()+h);
canvas.drawText(text, x, y, pText);
imageView.setImageBitmap(newBitmap);
}
private void setTextSizeForWidth(Paint paint, float desiredHeight,
String text) {
// Pick a reasonably large value for the test. Larger values produce
// more accurate results, but may cause problems with hardware
// acceleration. But there are workarounds for that, too; refer to
//
final float testTextSize = 48f;
// Get the bounds of the text, using our testTextSize.
paint.setTextSize(testTextSize);
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
// Calculate the desired size as a proportion of our testTextSize.
float desiredTextSize = testTextSize * desiredHeight / bounds.height();
// Set the paint for that size.
paint.setTextSize(desiredTextSize);
}
编辑:-
除了上面的 addStampToImage 方法,您还可以使用更新后的 addStampToImage 方法,如下所示:-
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
String text = "Maulik";
Paint pText = new Paint();
pText.setColor(Color.WHITE);
setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
Rect textHeightWidth = new Rect();
pText.getTextBounds(text, 0, text.length(), textHeightWidth);
canvas.drawText(text, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
pText);
imageView.setImageBitmap(newBitmap);
}
我想要的:我想在我从图库或相机中选择的图像底部添加文本。
原图
我在底部的图像中添加了蓝色色带
在那个条带中,我想恰好在中间添加一些文本。
问题是什么:
- 我无法将文本准确定位在蓝色色带的中间。
- 对于不同的图片,文字大小会发生变化。有的时候很小,有的时候很大。
我试过的:我的代码如下。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageView);
}
public void openGallery(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 100);
}
public void openCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 101);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && resultCode == Activity.RESULT_OK) {
if (requestCode == 100) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media
.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
addStampToImage(bitmap);
} else if (requestCode == 101) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
addStampToImage(bitmap);
}
}
}
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
Paint pText = new Paint();
pText.setColor(Color.WHITE);
pText.setTextSize((int) (20 * scale));
String text = "Maulik";
/*Rect r = new Rect();
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
pText.setTextAlign(Paint.Align.LEFT);
pText.getTextBounds(text, 0, text.length(), r);
float x = -r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
int minusSpace = (int) (canvas.getClipBounds().bottom * 0.07);
canvas.drawText(text, 0, canvas.getClipBounds().bottom - minusSpace, pText);*/
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
int x = (newBitmap.getWidth() - bounds.width())/6;
int y = (newBitmap.getHeight() + bounds.height())/5;
canvas.drawText(text, x * scale, y * scale, pText);
mImageView.setImageBitmap(newBitmap);
}
}
任何帮助将不胜感激!
更新时间:2018 年 8 月 1 日
addStampToImage 方法中的更改。
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Rect textHeightWidth = new Rect();
pText.getTextBounds(fromWhichMode, 0, fromWhichMode.length(), textHeightWidth);
canvas.drawText(textToStamp, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
pText);
以上更改使我在蓝色条带中间显示了文本。但核心 ISSUE 保持不变。即文本大小会根据不同的图像大小而变化。
试试这个我觉得对你有帮助
/** * 对于水印 */
public static Bitmap waterMark(Bitmap src, String watermark, Point location, int color, int alpha, int size, boolean underline) {
int[] pixels = new int[100];
//get source image width and height
int widthSreen = src.getWidth(); // 1080L // 1920
int heightScreen = src.getHeight(); // 1343L // 2387
Bitmap result = Bitmap.createBitmap(widthSreen, heightScreen, src.getConfig());
//create canvas object
Canvas canvas = new Canvas(result);
//draw bitmap on canvas
canvas.drawBitmap(src, 0, 0, null);
//create paint object
Paint paint = new Paint();
// //apply color
// paint.setColor(color);
// //set transparency
// paint.setAlpha(alpha);
// //set text size
size = ((widthSreen * 5) / 100);
paint.setTextSize(size);
// paint.setAntiAlias(true);
// //set should be underlined or not
// paint.setUnderlineText(underline);
//
// //draw text on given location
// //canvas.drawText(watermark, w / 4, h / 2, paint);
Paint.FontMetrics fm = new Paint.FontMetrics();
paint.setColor(Color.WHITE);
// paint.setTextSize(18.0f);
paint.getFontMetrics(fm);
int margin = 5;
canvas.drawRect(50 - margin, 50 + fm.top - margin,
50 + paint.measureText(watermark) + margin, 50 + fm.bottom
+ margin, paint);
paint.setColor(Color.RED);
canvas.drawText(watermark, 50, 50, paint);
return result;
}
在您的 onActivityResult 上调用此方法
Bitmap bitmapp = waterMark(bitmap, your_string, p, Color.RED, 90, 90, true);
检查以下代码:-
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
String text = "Maulik";
Paint pText = new Paint();
pText.setColor(Color.WHITE);
setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
int x= ((newBitmap.getWidth()-(int)pText.measureText(text))/2);
int h=(extraHeight+bounds.height())/2;
int y=(originalBitmap.getHeight()+h);
canvas.drawText(text, x, y, pText);
imageView.setImageBitmap(newBitmap);
}
private void setTextSizeForWidth(Paint paint, float desiredHeight,
String text) {
// Pick a reasonably large value for the test. Larger values produce
// more accurate results, but may cause problems with hardware
// acceleration. But there are workarounds for that, too; refer to
//
final float testTextSize = 48f;
// Get the bounds of the text, using our testTextSize.
paint.setTextSize(testTextSize);
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
// Calculate the desired size as a proportion of our testTextSize.
float desiredTextSize = testTextSize * desiredHeight / bounds.height();
// Set the paint for that size.
paint.setTextSize(desiredTextSize);
}
编辑:- 除了上面的 addStampToImage 方法,您还可以使用更新后的 addStampToImage 方法,如下所示:-
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
String text = "Maulik";
Paint pText = new Paint();
pText.setColor(Color.WHITE);
setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
Rect textHeightWidth = new Rect();
pText.getTextBounds(text, 0, text.length(), textHeightWidth);
canvas.drawText(text, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
pText);
imageView.setImageBitmap(newBitmap);
}