android - Canvas.drawBitmap 使用 Bitmap 的最后内容进行所有调用
问题描述
我正在尝试在 Xamarin 中的自定义视图上呈现多个 PDF 页面。
public override void Draw( AG.Canvas canvas ) {
base.Draw( canvas );
if( !(Parent is AW.ScrollView p) || pdfRenderer == null )
return;
int topPage = pdfRenderer.PageCount * p.ScrollY / Height;
while( topPage < pdfRenderer.PageCount && topPage * screenPageHeight < p.ScrollY + p.Height ) {
using( var page = pdfRenderer.OpenPage( topPage ) ) {
page.Render( bitmap, null, null, PdfRenderMode.ForDisplay );
page.Close();
}
AG.Rect pageRect = new AG.Rect {
Left = 0,
Top = topPage * screenPageHeight,
Right = Width,
Bottom = (topPage + 1) * screenPageHeight,
};
canvas.DrawBitmap( bitmap, null, pageRect, null );
topPage++;
}
}
输出是从所有 pageRect 中运行的最后一个循环绘制页面。我可以想象为什么会发生这种情况,但真正的问题是如何修复此代码以绘制所有页面,而无需为每个页面创建单独的位图。
编辑。附上调试器屏幕截图。(在 canvas.DrawBitmap 断点处)
编辑。添加了java代码。预期:一个红色和一个绿色矩形。观察到:两个绿色矩形。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TestView());
}
class TestView extends View {
public TestView() {
super(MainActivity.this);
}
Bitmap bmp = Bitmap.createBitmap(600, 200, Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
void FillBitmap(int color) {
Canvas canvas = new Canvas(bmp);
canvas.drawColor(color);
}
protected void onDraw (Canvas canvas) {
FillBitmap(Color.RED);
canvas.drawBitmap(bmp, 60, 120, paint);
FillBitmap(Color.GREEN);
canvas.drawBitmap(bmp, 60, 440, paint);
}
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(720, 720);
}
}
}
解决方案
David 和我相信这与使用 Canvas 和从同一资源加载的 Drawable 对象有关。位图是可绘制的。Xamarin 是 API 上的一个非常薄的包装层,因此这可能与 Xamarin 无关,但更特定于 Android。请注意文档的这一部分: 注意:项目中的每个唯一资源只能保持一种状态,无论您为其实例化了多少不同的对象。例如,如果您从同一个图像资源中实例化两个 Drawable 对象并更改一个对象的属性(例如 alpha),那么它也会影响另一个对象。在处理图像资源的多个实例时,您应该执行补间动画,而不是直接转换 Drawable 对象。- https://developer.android.com/guide/topics/graphics/drawables -https://developer.android.com/reference/android/graphics/Canvas 因此,最可能的原因是您正在从同一资源(pdf)创建位图实例。我无法在您的代码片段中看到这一点来确认,但这是最可能的原因。它也可能与重复使用相同的位图实例有关,而不是与多个单独的位图实例有关,但我也无法从片段中看到这一点。与前面提到的 Canvas 上的 Drawables 问题相比,它可能不太可能是原因。检查补间动画是否会对您的场景有所帮助。
但请注意,可能有更简化的方法来呈现 PDF。Android(和 Xamarin.Andriod)有用于 PdfRenderer 的 API。Android 的文档在这里:https ://developer.android.com/reference/android/graphics/pdf/PdfRenderer Xamarin.Android 我们在这里有 Xamarin 包装器的 API 文档:https ://developer.xamarin.com/ api/type/Android.Graphics.Pdf.PdfRenderer/ 或者,您还可以将 pdf 设置为 Xamarin.Android 或 Xamarin.Forms 中 WebView 的源,方法是将 Source 属性设置为 Xamarin.Forms.WebView 或通过从 Android.Webkit.WebView 的实例调用 LoadUrl。
推荐阅读
- laravel - Laravel 在发送邮件之前检查用户是否被停用
- dart - Dart linting 排除分析器下的文件夹
- vue.js - 如何将标签/插槽添加到输入字段 Vue
- php - 如何解决此错误:ORA-01741:非法零长度标识符
- reactjs - 防止状态重置
- anaconda - 在 anaconda navigator 中启动软件包的问题
- debugging - 如何在 Blazor 中跟踪和调试路由(服务器端)
- vba - 如何在Access数据输入表单中仅查询当前记录/行的组合框?
- excel - 如何使 VLOOKUP() 与下一个更大的值匹配?
- git - git log --since 不包括第一次提交