我正在编写一个OpenGL使用的简单应用程序GLUT.我不想滚动自己的字体渲染代码,而是想使用附带的简单位图字体GLUT.让他们工作的步骤是什么?
我正在处理我正在处理的Android应用程序上的位图问题.假设发生的是应用程序从网站下载图像,将它们保存到设备,将它们作为位图加载到内存中,并将其显示给用户.首次启动应用程序时,这一切都正常.但是,我为删除了图像的用户添加了刷新选项,并且上面概述的过程从头开始.
我的问题:通过使用刷新选项,旧图像仍然在内存中,我很快就会得到OutOfMemoryErrors.因此,如果图像正在刷新,我让它通过arraylist并回收旧图像.但是,当应用程序将新图像加载到arraylist中时,它会因"尝试使用回收的位图"错误而崩溃.
据我了解,回收位图会破坏位图并为其他对象释放内存.如果我想再次使用位图,则必须重新初始化.我相信当新文件加载到arraylist时我正在这样做,但是仍然有问题.非常感谢任何帮助,因为这非常令人沮丧.问题代码如下.谢谢!
public void fillUI(final int refresh) {
// Recycle the images to avoid memory leaks
if(refresh==1) {
for(int x=0; x<images.size(); x++)
images.get(x).recycle();
images.clear();
selImage=-1; // Reset the selected image variable
}
final ProgressDialog progressDialog = ProgressDialog.show(this, null, this.getString(R.string.loadingImages));
// Create the array with the image bitmaps in it
new Thread(new Runnable() {
public void run() {
Looper.prepare();
File[] fileList = new File("/data/data/[package name]/files/").listFiles();
if(fileList!=null) {
for(int x=0; x<fileList.length; x++) {
try {
images.add(BitmapFactory.decodeFile("/data/data/[package name]/files/" + fileList[x].getName()));
} catch …Run Code Online (Sandbox Code Playgroud) 我偶尔会从Market开发者控制台获得这个堆栈跟踪; 我找不到任何方法来重现错误.在应用程序首次加载时显示启动画面ImageView时会发生这种情况,但堆栈跟踪没有任何代码.我甚至认为我的活动甚至没有达到onCreate,尽管没有日志很难说.
实际上,我从未在代码中的任何地方使用过Bitmap.我对图像的唯一引用是在我的layout.xml中.
<ImageView android:id="@+id/splashScreen"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:src="@drawable/splashscreen"
android:scaleType="fitXY"
/>
Run Code Online (Sandbox Code Playgroud)
我对这个ImageView做的唯一事情是设置它GONE在我完成启动时的可见性.
我能做些什么吗?
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4721ec18
at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
at android.widget.ImageView.onDraw(ImageView.java:923)
at android.view.View.draw(View.java:6761)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.buildDrawingCache(View.java:6517)
at android.view.View.getDrawingCache(View.java:6305)
at android.view.ViewGroup.drawChild(ViewGroup.java:1588)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1409)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at …Run Code Online (Sandbox Code Playgroud) 我使用以下方法将图像加载到Picture Box中:
picturebox1.Image = Image.FromFile()
Run Code Online (Sandbox Code Playgroud)
我用以下方法保存它:
Bitmap bm = new Bitmap(pictureBox1.Image);
bm.Save(FileName, ImageFormat.Bmp);
Run Code Online (Sandbox Code Playgroud)
它在创建新文件时工作得很好,但是当我尝试替换现有图像时,我会抛出以下运行时错误:
GDI +中发生了一般错误
那么我该怎么做才能解决这个问题呢?
from Tkinter import *
root = Tk()
cv = Canvas(root)
cv.create_rectangle(10,10,50,50)
cv.pack()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
我想将画布内容转换为位图或其他图像,然后执行其他操作,例如旋转或缩放图像,或更改其坐标.
位图可以提高效率,以显示我是否不再绘图.
我该怎么办?
我正在测试android 3.1,大堆大小的选项,大约250M的内存可用.
每当我点击应用程序首选项中的"测试"按钮时,我都会设置以下代码:
float [][][]foo = new float[3][2048][2048];
Bitmap bm = Bitmap.createBitmap(2048, 2048, Bitmap.Config.ARGB_8888);
bm.recycle();
bm = null;
foo = null;
Run Code Online (Sandbox Code Playgroud)
我有足够的记忆 - 我可以毫无问题地按几下按钮.
但是,如果我一直按下按钮,最终(少于20次点击)它会以OutOfMemory消失.[通常在android.graphics.Bitmap.nativeCreate(Native Method)中]
没有其他事情发生 - 我永远不必离开PreferencesActivity.当我点击按钮时,还会显示一个小Toast,因此正在进行少量其他UI活动.
这是由于碎片,还是Android Bitmap代码和/或GC中的一个可怕的错误?或者我只是在做一些愚蠢的事情?(请让它成为愚蠢的......)
有人有解决方法吗?因为上面的代码完全代表了我的代码每次用户调用它时所要做的事情,而且现在尽管细致地清除了变量,但它在几次使用后就会死掉.(这已经让我疯了很久了!)
[更新]
我已经确认这是一个碎片问题或gc错误,因为堆转储显示我在闲置(没有泄漏)时只使用5.6M处理期间大约26M达到峰值.(此外,本机堆保持在4M以下.)虽然java堆同时在我的测试设备上一直增长到280M限制,此时我开始获得OutOfMemory异常.所以我在峰值时只使用了10%的可用堆,但是获得OutOfMemory.
[不幸的是,添加对System.gc()的调用修复了我上面给出的简单测试用例.我说不幸,因为(A)它不应该有所作为,(B)因为我已经在我的实际代码中定期调用它,所以这意味着我上面的简单测试用例太简单了.
有没有其他人遇到这个?任何解决方法?有没有一种优雅的方式来重新启动我的应用程序?
[更新]
以下版本可以在3到4次调用中可靠地导致OutOfMemory(按下按钮):
float [][][]foo = new float[3][2048][2048];
Bitmap bm = Bitmap.createBitmap(2048, 2048, Bitmap.Config.ARGB_8888);
int []bar = new int[3*2048*2048];
bm.recycle();
bm = null;
System.gc();
foo = null;
System.gc();
bar = null;
System.gc();
Run Code Online (Sandbox Code Playgroud)
内存跟踪显示堆在每次调用时稳定增长,直到达到限制并死亡.如果我删除三个分配中的任何一个,它就会达到平衡并无限期地存活下来.删除除最后一个gc()之外的所有gc()会导致它稍早死亡.
我会说这是一个碎片问题,而不是gc bug本身.如果有人知道如何解决它,请告诉我.int []分配用于编写位图,因此我没有选择将其分配为2d数组(android Bitmap库的限制).
我使用下面的方法来制作带圆角的位图.现在我想在位图周围画一条线.
private BitmapDrawable roundCornered(BitmapDrawable scaledBitmap, int i) {
Bitmap bitmap = scaledBitmap.getBitmap();
result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
color = 0xff424242;
paint = new Paint();
rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
rectF = new RectF(rect);
roundPx = i;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.BLUE);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
BitmapDrawable finalresult = new BitmapDrawable(result);
return finalresult;
}
Run Code Online (Sandbox Code Playgroud)
我得到了下面的图片,但我的实际需要是我必须在图像周围画一个边框.

我收到以下编译时错误:
The type or namespace name 'Bitmap' could not be found (are you missing a using directive or an assembly reference?)
这是我的代码:
BitmapImage img = new BitmapImage();
Run Code Online (Sandbox Code Playgroud) 我有一个按钮,我希望当我点击它时图像被保存到SD卡(或内部存储器,如在htc一个x我们没有像SD卡那样的外部存储器)
这是我的代码:
sd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
MpClick.start();
File myDir=new File("/sdcard/Saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
bitMapToShare.compress(Bitmap.CompressFormat.JPEG, 600, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
Run Code Online (Sandbox Code Playgroud)
如何在其中显示一条消息,其中写着"您的图像已保存".像一个警报但是2秒然后消失
我正在尝试将色调应用于<layer-list>中的位图
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="@color/grey" />
<size android:width="45dp" android:height="45dp"/>
</shape>
</item>
<item android:left="5dp" android:right="5dp" android:top="5dp" android:bottom="5dp">
<bitmap android:src="@drawable/ic_action" android:tint="#FF000000" />
</item>
</layer-list>
Run Code Online (Sandbox Code Playgroud)
预览显示它应该工作,FROM ANDROID-STUDIO:

但是在设备上部署时它不会着色: 
如果我在布局中使用ImageView,它确实正确着色,但是使用了图层列表失败了.我相信我已经尝试过每一个没有结果的tintMode.