我正在研究一个Android应用程序。 该应用程序有一个包含大量图像的视图。 我有一个错误,我会尽量提供尽可能多的信息,希望有人能给我一些build议。 该应用程序在所有的本地testing中工作良好。 但是,我收到了很多来自用户的崩溃: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 这是堆栈跟踪 0 java.lang.OutOfMemoryError: bitmap size exceeds VM budget 1 at android.graphics.Bitmap.nativeCreate(Native Method) 2 at android.graphics.Bitmap.createBitmap(Bitmap.java:507) 3 at android.graphics.Bitmap.createBitmap(Bitmap.java:474) 4 at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:379) 5 at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:498) 6 at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:473) 7 at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 8 at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:359) 9 at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:385) 我最大的问题是,即使在旧设备上,我也无法在本地重现问题。 我已经实现了很多东西来解决这个问题: 没有内存泄漏 :我确定没有内存泄漏。 当我不需要他们时,我删除了这些意见。 我也回收了所有的位图,并确保垃圾收集器正常工作。 我在onDestroy()方法中实现了所有必要的步骤 图像大小正确缩放 […]
我发现了几种优化WPF中的位图处理的模式。 但是,我不知道何时使用每种模式。 正如我认为这是一个普遍的问题,我总结了我的理解和我的猜想,并寻求你的帮助。 如果你可以添加模式 ,解释它们的不同之处 ,说明它们是使用CPU还是使用GPU ,以及什么时候使用它们以及如何合并它们 ,那将会是一个巨大的帮助! 上下文 – 图片“网格”场景: 我的应用程序必须显示许多位图图像。 图像显示在屏幕上的行和列网格组织(不一定是网格或UniformGrid类,认为窗口媒体播放器的相册视图)。 图像可能会在不同的网格单元之间移 任意单元格中的一些图像可能被其他单元replace。 图像应该是可点击的,应该提供一个上下文菜单,应该是可select的,可拖拽的等等。换句话说,“将小编辑器合并成一个大的位图”是不适用的,至less不是天真的。 模式0:黑客 把这些小杂烩混合成一个位图(如何绘制上下文?),并将其作为背景。 覆盖这与图像与空的内容,将处理命中,上下文菜单,事件等 优点是我们只在这里讲两个位图:当前显示的和应该replace的位图。 这应该是非常快的。 但是,我多年的经验提高了危险的红旗。 你的评论? 模式1:缩小图像大小 当你事先知道要调整的图像大小,以及当你准备失去performance的细节(颜色)时,这是一个不容小觑的过程: 使用BitmapImage.DecodePixelWidth减小位图大小 使用FormatConvertedBitmap.DestinationFormat减less颜色信息 将控件的缩放行为设置Image.Stretch设置为Stretch.None 将图像的SetBitmapScalingMode设置为LowQuality。 冻结bug子手 在这里看代码。 模式2:背景预取 当您认为您可以利用用户凝视屏幕上的图像并准备好接下来要显示的图像时,此模式适用。 除了内存开销之外,项目的缺点是必须支持.Net Framework 4目标,而不仅仅是客户端configuration文件,因此可能会导致客户端上的安装。 你自己将不得不忍受asynchronous编程的痛苦。 在这种模式下,您可以创build所需数量的图像控件。 当需要添加,移动或删除位图时,只能修改图像控件的位图源。 BackgroundWorker任务负责预取BitmapSource(可能使用上面的“缩小图像大小”模式)并将其插入到MemoryCache中。 为此,您必须将BitmapImage的CacheOption设置为OnLoad,以便工作被卸载到后台工作者。 模式3:绘图上下文 这是Microsoft支持部门的Sheldon Ziao在MSDN WPF论坛上提出的build议。 请参阅Adam Nathan的WPF 4的第15章“2Dgraphics”中的494页,了解DrawingContext的描述。 我不能说我明白这一点。 根据这里的答案,我会认为这将改善处理几何图纸,而不是位图。 接下来,我不认为这将支持图像的焦点和事件要求(我不好意思,因为没有在论坛上更好地解释要求)而且,我担心这本书的总结性的句子:“请注意,使用DrawingContext不会改变您在保留模式系统中运行的事实。 指定的绘图不会立即发生; 这些命令被WPF所保留,直到需要为止。“这意味着,一旦我们的处理程序重新开始,我们就不能像”后台预取“那样利用并行性。 模式4:可写位图 这里的MSDN文档将其描述为双缓冲系统:您的UI线程更新缓冲区; […]
我需要在.net中压缩图像的方法,所以我查看使用.net GZipStream类(或DeflateStream)。 然而,我发现减压并不总是成功的,有时图像将解压罚款和其他时间,我会得到一个GDI +错误的东西是损坏的。 在调查了这个问题之后,我发现解压并没有给出它压缩的所有字节。 所以,如果我压缩2257974字节,我有时会回来只有2257870字节(实数)。 最有趣的是,有时它会工作。 所以我创build了这个压缩只有10个字节的小testing方法,现在我什么也没有回来。 我试了压缩类GZipStream和DeflateStream,我仔细检查了我的代码可能的错误。 我甚至尝试将stream定位到0,并冲洗所有的stream,但没有运气。 这是我的代码: public static void TestCompression() { byte[] test = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] result = Decompress(Compress(test)); // This will fail, result.Length is 0 Debug.Assert(result.Length == test.Length); } public static byte[] Compress(byte[] data) { var […]
我正在裁剪图像类,但遇到一个回收的位图问题: 03-02 23:14:10.514: E/AndroidRuntime(16736): FATAL EXCEPTION: Thread-1470 03-02 23:14:10.514: E/AndroidRuntime(16736): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@428e5450 03-02 23:14:10.514: E/AndroidRuntime(16736): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026) 03-02 23:14:10.514: E/AndroidRuntime(16736): at android.graphics.Canvas.drawBitmap(Canvas.java:1096) 03-02 23:14:10.514: E/AndroidRuntime(16736): at android.graphics.Bitmap.createBitmap(Bitmap.java:604) 03-02 23:14:10.514: E/AndroidRuntime(16736): at eu.janmuller.android.simplecropimage.CropImage$1.prepareBitmap(CropImage.java:630) 03-02 23:14:10.514: E/AndroidRuntime(16736): at eu.janmuller.android.simplecropimage.CropImage$1.run(CropImage.java:636) 03-02 23:14:10.514: E/AndroidRuntime(16736): at eu.janmuller.android.simplecropimage.CropImage$6.run(CropImage.java:343) 03-02 23:14:10.514: E/AndroidRuntime(16736): at eu.janmuller.android.simplecropimage.Util$BackgroundJob.run(Util.java:175) 03-02 […]
我想要一个带有粗体文本的位图图标在地图上绘制。 我有一个片段写在图像上的文字: Bitmap icon = BitmapFactory.decodeResource(PropertyMapList.this.getResources(), R.drawable.location_mark); TextPaint paint = new TextPaint(); paint.setColor(Color.BLACK); paint.setTextSize(14); paint.setFakeBoldText(true); //paint.setTextAlign(Align.CENTER); Bitmap copy = icon.copy(Bitmap.Config.ARGB_8888, true); Canvas canvas = new Canvas(copy); //canvas.drawText(jsonObj.getString("district_name"), 5, canvas.getHeight()/2, paint); String districtName = jsonObj.getString("district_name"); StaticLayout layout = new StaticLayout((districtName.length()>25 ? districtName.substring(0, 24)+"..":districtName)+"\n"+jsonObj.getString("total_properties"), paint, canvas.getWidth()-10,Layout.Alignment.ALIGN_CENTER, 1.3f, 0, false); canvas.translate(5, canvas.getHeight()/2); //position the text layout.draw(canvas); setFakeBoldText(true)不适用于我。 我想要在位图上绘制的文本加粗。
我想在网站上使用CSS精灵 ,而不是单独的图像文件,大量的小图标都是相同的大小。 我怎样才能使用ImageMagick连接(平铺)成一个大的图像?
我正在尝试使用以下函数将位图旋转90度。 它的问题是,当高度和宽度不相等时,会切断部分图像。 注意returnBitmap的width = original.height,它的height = original.width 任何人都可以帮我解决这个问题,或指出我做错了什么? private Bitmap rotateImage90(Bitmap b) { Bitmap returnBitmap = new Bitmap(b.Height, b.Width); Graphics g = Graphics.FromImage(returnBitmap); g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2); g.RotateTransform(90); g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2); g.DrawImage(b, new Point(0, 0)); return returnBitmap; }
背景 大多数情况下,在Android上获得OOM是由于使用了太多的位图和/或创build大的位图。 最近我决定尝试JNI,以便通过将数据本身存储在JNI端来避免OOM。 经过一段时间的搞乱JNI后,我已经创build了一些post寻求帮助和分享我的知识,我现在决定与你分享一些更多的代码。 这里是任何人有兴趣阅读发现或贡献的post: 如何将位图caching到本机内存 在android上使用JNI进行图像解码和操作 JNI – 如何使用不同字段的多个Jni包装实例? 使用JNI和NDK旋转位图 这一次,我添加了存储,恢复,裁剪和旋转位图的function。 应该很容易添加更多的选项, 如果其他人在这里将他们自己的代码添加到更有用的function , 我会很高兴 。 所以我要展示的代码实际上是我创build的所有东西的合并。 使用示例代码: Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher); final int width=bitmap.getWidth(),height=bitmap.getHeight(); // store the bitmap in the JNI "world" final JniBitmapHolder bitmapHolder=new JniBitmapHolder(bitmap); // no need for the bitmap on the java "world", since the operations are done on the JNI "world" […]
我正试图在canvas上开发一个应用程序,我在canvas上绘制位图。绘制完成后,我正在尝试将其转换为位图图像。 谁能给我一个build议。 先谢谢你。
我有一个ImageView,我想使它与rounded corners 。 我使用这个: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@null"/> <stroke android:width="1dp" android:color="#ff000000"/> <corners android:radius="62px"/> </shape> 并将此代码设置为我的imageview的背景。 它的工作原理,但是我放在ImageView上的src图像是走出了边界,并不适应新的形状。 我该如何解决这个问题?