canvas.drawText canvas 上的像素完美文本
canvas.drawText with pixel perfect text on a canvas
THIS IS NOT ABOUT AntiAlias, Please read the question before answering thank you.
增加赏金 --> android convert text width (in pixels) to percent of screen width/height
质量信息 -->
我尝试在 canvas 上绘制文本时得到不一致的结果。请帮忙,谢谢。
我希望文本在所有设备上使用相同数量的缩放space
我不关心 ANTI_ALIAS 并添加了 paint.setFlags(Paint.ANTI_ALIAS_FLAG);
但问题是一样的...
在一个屏幕上,文本占据了一半的宽度,在另一个屏幕上只有 1/3,甚至在一个屏幕上占据了整个宽度。
我希望他们都使用相同数量的屏幕空间。
例如
1600X900 7寸Kitkat平板实物图:
1920.1080 5.2 奇巧物理
1600x900 20 英寸棒棒糖模拟
1280x720 4.7英寸
这些是使用 http://www.gkproggy.com/2013/01/draw-text-on-canvas-with-font-size.html
中的指南创建的
该教程显示一致的结果
为了彻底,这里是来源:
public class MainActivity extends Activity
{
Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
paint = new Paint();
View test = new TestView(this);
setContentView(test);
}
public class TestView extends View
{
public TestView(Context context)
{
super(context);
setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
public float pixelsToSp(Context context, float px) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px/scaledDensity;
}
public float spToPixels(float sp) {
Context context = getContext();
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return scaledDensity*sp;
}
@Override
protected void onDraw(Canvas canvas)
{
int size = getResources().getDimensionPixelSize(R.dimen.sp20);
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
Log.v("intSize", Integer.toString(size));
Log.v("intSize", Integer.toString(px));
Log.v("intSize", Float.toString(spToPixels(20f)));
if(true) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ultra.ttf");
paint.setTypeface(myTypeface);
}
paint.setColor(Color.BLACK);
paint.setTextSize(size);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size, paint);
super.onDraw(canvas);
}
}
}
我已经尝试过来自
正在研究这个
<-- 现在试试
使用的资源:
必须获取屏幕宽度,文本大小与屏幕比例的一些参考,并进行计算。所以结果是:
和
注意第二个 HELLOOOOOOOOOOOOOOOOO!
public class MainActivity extends Activity
{
Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
paint = new Paint();
View test = new TestView(this);
setContentView(test);
}
public class TestView extends View
{
public TestView(Context context)
{
super(context);
setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
public float pixelsToSp(float px) {
Context context = getContext();
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px/scaledDensity;
}
public float spToPixels(float sp) {
Context context = getContext();
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return scaledDensity*sp;
}
@Override
protected void onDraw(Canvas canvas)
{
int size = getResources().getDimensionPixelSize(R.dimen.sp20);
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
Log.v("intSize", Integer.toString(size));
Log.v("intSize", Integer.toString(px));
Log.v("intSize", Float.toString(spToPixels(20f)));
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Log.v("intSize hm", Integer.toString(metrics.heightPixels));
Log.v("intSize wm", Integer.toString(metrics.widthPixels));
if(true) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ultra.ttf");
paint.setTypeface(myTypeface);
}
paint.setColor(Color.BLACK);
paint.setTextSize(size);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size, paint);
setTextSizeForWidth(paint, metrics.widthPixels * 0.5f, "HELLOOOOOOOOOOOOOO!");
canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size*3, paint);
super.onDraw(canvas);
}
/**
* Sets the text size for a Paint object so a given string of text will be a
* given width.
*
* @param paint
* the Paint to set the text size for
* @param desiredWidth
* the desired width
* @param text
* the text that should be that width
*/
private void setTextSizeForWidth(Paint paint, float desiredWidth,
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 * desiredWidth / bounds.width();
// Set the paint for that size.
paint.setTextSize(desiredTextSize);
}
}
}
请注意,如果您不扩展 Activity,请使用
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
而不是
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
THIS IS NOT ABOUT AntiAlias, Please read the question before answering thank you.
增加赏金 --> android convert text width (in pixels) to percent of screen width/height
质量信息 -->
我尝试在 canvas 上绘制文本时得到不一致的结果。请帮忙,谢谢。
我希望文本在所有设备上使用相同数量的缩放space
我不关心 ANTI_ALIAS 并添加了 paint.setFlags(Paint.ANTI_ALIAS_FLAG);
但问题是一样的...
在一个屏幕上,文本占据了一半的宽度,在另一个屏幕上只有 1/3,甚至在一个屏幕上占据了整个宽度。
我希望他们都使用相同数量的屏幕空间。
例如
1600X900 7寸Kitkat平板实物图:
1920.1080 5.2 奇巧物理
1600x900 20 英寸棒棒糖模拟
1280x720 4.7英寸
这些是使用 http://www.gkproggy.com/2013/01/draw-text-on-canvas-with-font-size.html
中的指南创建的该教程显示一致的结果
为了彻底,这里是来源:
public class MainActivity extends Activity
{
Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
paint = new Paint();
View test = new TestView(this);
setContentView(test);
}
public class TestView extends View
{
public TestView(Context context)
{
super(context);
setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
public float pixelsToSp(Context context, float px) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px/scaledDensity;
}
public float spToPixels(float sp) {
Context context = getContext();
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return scaledDensity*sp;
}
@Override
protected void onDraw(Canvas canvas)
{
int size = getResources().getDimensionPixelSize(R.dimen.sp20);
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
Log.v("intSize", Integer.toString(size));
Log.v("intSize", Integer.toString(px));
Log.v("intSize", Float.toString(spToPixels(20f)));
if(true) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ultra.ttf");
paint.setTypeface(myTypeface);
}
paint.setColor(Color.BLACK);
paint.setTextSize(size);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size, paint);
super.onDraw(canvas);
}
}
}
我已经尝试过来自
正在研究这个
<-- 现在试试
使用的资源:
必须获取屏幕宽度,文本大小与屏幕比例的一些参考,并进行计算。所以结果是:
和
注意第二个 HELLOOOOOOOOOOOOOOOOO!
public class MainActivity extends Activity
{
Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
paint = new Paint();
View test = new TestView(this);
setContentView(test);
}
public class TestView extends View
{
public TestView(Context context)
{
super(context);
setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
public float pixelsToSp(float px) {
Context context = getContext();
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px/scaledDensity;
}
public float spToPixels(float sp) {
Context context = getContext();
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return scaledDensity*sp;
}
@Override
protected void onDraw(Canvas canvas)
{
int size = getResources().getDimensionPixelSize(R.dimen.sp20);
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
Log.v("intSize", Integer.toString(size));
Log.v("intSize", Integer.toString(px));
Log.v("intSize", Float.toString(spToPixels(20f)));
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Log.v("intSize hm", Integer.toString(metrics.heightPixels));
Log.v("intSize wm", Integer.toString(metrics.widthPixels));
if(true) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Ultra.ttf");
paint.setTypeface(myTypeface);
}
paint.setColor(Color.BLACK);
paint.setTextSize(size);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size, paint);
setTextSizeForWidth(paint, metrics.widthPixels * 0.5f, "HELLOOOOOOOOOOOOOO!");
canvas.drawText("HELLOOOOOOOOOOOOOO!", 0, size*3, paint);
super.onDraw(canvas);
}
/**
* Sets the text size for a Paint object so a given string of text will be a
* given width.
*
* @param paint
* the Paint to set the text size for
* @param desiredWidth
* the desired width
* @param text
* the text that should be that width
*/
private void setTextSizeForWidth(Paint paint, float desiredWidth,
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 * desiredWidth / bounds.width();
// Set the paint for that size.
paint.setTextSize(desiredTextSize);
}
}
}
请注意,如果您不扩展 Activity,请使用
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
而不是
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);