画质后,许多drawBitmap的变差

我的程序绘制动态壁纸画布上的位图。 它的工作原理,但一段时间后的图像变得很糟糕( 画质后,许多drawBitmap的变差

任何想法,为什么?

package com.tripr; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Paint.Align; import android.location.Address; import android.location.Geocoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.service.wallpaper.WallpaperService; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; /* * This animated wallpaper draws a rotating wireframe cube. */ public class MyWallpaperService extends WallpaperService{ private final String TAG = "tripr"; @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); } @Override public Engine onCreateEngine() { return new CubeEngine(this); } class CubeEngine extends Engine implements LocationListener{ private MyWallpaperService mws; private float xOffset; private float xStep; private int xPixels; private String lastPhotoUrl = ""; private LocationManager lm; private Bitmap bmp = null; private String locationName; private String status = "waiting for location update..."; private final Handler mHandler = new Handler(); private final Runnable mDrawBtmp = new Runnable() { public void run() { drawFrame(); } }; private boolean mVisible; CubeEngine(MyWallpaperService mymws) { mws = mymws; lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); requestLocationUpdates(); MyThread myThread = new MyThread(lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)); myThread.start(); } //taken from http://p-xr.com/android-tutorial-how-to-parse-read-json-data-into-a-android-listview/ private JSONObject getJSONfromURL(String url){ //initialize InputStream is = null; String result = ""; JSONObject jArray = null; //http post try{ HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet(url); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); is = entity.getContent(); }catch(Exception e){ Log.e(TAG, "Error in http connection "+e.toString()); } //convert response to string try{ BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); result=sb.toString(); }catch(Exception e){ Log.e(TAG, "Error converting result "+e.toString()); } //try parse the string to a JSON object //Log.d(TAG, result); try{ jArray = new JSONObject(result); }catch(JSONException e){ Log.e(TAG, "Error parsing data "+e.toString()); } return jArray; } String getFlickrUrl(double lat, double lon, double radius){ return "http://api.flickr.com/services/rest/?" + "method=flickr.photos.search" + "&api_key=a6d9db5ff2885dd2f8949590e7a44762" + "&tags=architecture" + "&lat=" + lat + "&lon=" + lon + "&radius=" + radius + "&radius_units=km" + "&extras=geo%2Curl_z%2Ctags" + "&per_page=250" + "&format=json" + "&sort=interestingness-desc" + "&nojsoncallback=1"; } void requestLocationUpdates(){ if (!(lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))){ status = "locating over network disabled"; //bmp = null; } lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000*30, 10, this); } void removeUpdates(){ lm.removeUpdates(this); } @Override public void onLocationChanged(Location location) { MyThread myThread = new MyThread(location); myThread.start(); } @Override public void onProviderDisabled(String provider) {} @Override public void onProviderEnabled(String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onDestroy() { super.onDestroy(); mHandler.removeCallbacks(mDrawBtmp); } @Override public void onVisibilityChanged(boolean visible) { mVisible = visible; if (visible) { requestLocationUpdates(); drawFrame(); } else { mHandler.removeCallbacks(mDrawBtmp); removeUpdates(); } } @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { super.onSurfaceChanged(holder, format, width, height); drawFrame(); } @Override public void onSurfaceCreated(SurfaceHolder holder) { super.onSurfaceCreated(holder); } @Override public void onSurfaceDestroyed(SurfaceHolder holder) { super.onSurfaceDestroyed(holder); mVisible = false; mHandler.removeCallbacks(mDrawBtmp); } @Override public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) { /*Log.d(TAG, "onOffsetsChanged"); Log.d(TAG, "xOffset: " + String.valueOf(xOffset)); Log.d(TAG, "yOffset: " + String.valueOf(yOffset)); Log.d(TAG, "xStep: " + String.valueOf(xStep)); Log.d(TAG, "yStep: " + String.valueOf(yStep)); Log.d(TAG, "xPixels: " + String.valueOf(xPixels)); Log.d(TAG, "yPixels: " + String.valueOf(yPixels)); //Log.d(TAG, String.valueOf((xOffset / xStep))); Log.d(TAG, " ");*/ this.xPixels = xPixels; this.xStep = xStep; this.xOffset = xOffset; drawFrame(); } /* * Store the position of the touch event so we can use it for drawing later */ @Override public void onTouchEvent(MotionEvent event) { super.onTouchEvent(event); } /* * Draw one frame of the animation. This method gets called repeatedly * by posting a delayed Runnable. You can do any drawing you want in * here. This example draws a wireframe cube. */ void drawFrame() { final SurfaceHolder holder = getSurfaceHolder(); Canvas c = null; try { c = holder.lockCanvas(); if (c != null) { // draw something drawBmp(c); } } finally { if (c != null) holder.unlockCanvasAndPost(c); } // Reschedule the next redraw mHandler.removeCallbacks(mDrawBtmp); if (mVisible) { mHandler.postDelayed(mDrawBtmp, 1000 / 5); } } private class MyThread extends Thread { Location loc; MyThread(Location loc){ this.loc = loc; } public synchronized void run(){ // bringt synchronized was? weil wir kreieren ja immer eine neue intanz... try{ if (loc == null){ Log.d(TAG, "location is null"); return; } <SNIP> //the main code, update `status` and `bmp` } void drawBmp(Canvas canvas) { //canvas.restore(); //canvas.save(); //canvas.translate(0, 0); //canvas.drawColor(0xff00aa00); canvas.drawColor(Color.BLACK); if (bmp != null){ //int width = (int) (((double)bmp.getHeight()/(double)canvas.getHeight())*canvas.getWidth()); if (bmp.getHeight() != canvas.getHeight()){ Float width = new Float(bmp.getWidth()); Float height = new Float(bmp.getHeight()); Float ratio = width/height; Log.d(TAG, "scaling"); bmp = Bitmap.createScaledBitmap(bmp, (int)(canvas.getHeight()*ratio), canvas.getHeight(), true); } int x; if (bmp.getWidth() >= canvas.getWidth()){ x = -1*(int)((xOffset*(bmp.getWidth()-canvas.getWidth()))); }else{ x = (bmp.getWidth()-canvas.getWidth())/2; } //Log.d(TAG, String.valueOf(scale)); //Log.d(TAG, String.valueOf(canvas.getWidth())); //Log.d(TAG, " "); canvas.drawBitmap(bmp, x, 0, null); //canvas.drawLine(0, 0, bmp.getWidth(), 0, new Paint()); }else if(status != null){ Paint textPaint = new Paint(); textPaint.setColor(Color.WHITE); textPaint.setAntiAlias(true); textPaint.setTextSize(25); textPaint.setAlpha(120); textPaint.setTextAlign(Align.CENTER); canvas.drawText(status, canvas.getWidth()/2, canvas.getHeight()/2, textPaint); } if (locationName != null){ Paint textPaint = new Paint(); textPaint.setColor(Color.BLACK); textPaint.setAntiAlias(true); textPaint.setTextSize(30); textPaint.setAlpha(150); textPaint.setTextAlign(Align.LEFT); Rect rect = new Rect(); textPaint.getTextBounds(locationName, 0, locationName.length(), rect); //Log.d(TAG, String.valueOf(textPaint.getTextSize())); canvas.drawText(locationName, 0, 70, textPaint); } } } }

--------------解决方案-------------

drawBmp()反复把你的位图( bmp ),缩放(调用createScaledBitmap ),然后分配回bmp 。 随着时间的推移这些缩放操作会导致您看到的文物。

为了解决这个问题,存储在不同的变量(例如,原位private Bitmap originalImage;并创建由原来的缩放位图。

bmp = Bitmap.createScaledBitmap(originalImage, (int)(canvas.getHeight()*ratio), canvas.getHeight(), true);

分类:java的 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.185 (s). 10 q(s)