gpt4 book ai didi

java - 许多 drawBitmap 后图像质量变差

转载 作者:行者123 更新时间:2023-11-29 06:11:20 26 4
gpt4 key购买 nike

我的程序在动态壁纸 Canvas 上绘制位图。它有效,但一段时间后图像变得非常糟糕(http://img855.imageshack.us/img855/9756/deviceq.png)

有什么想法吗?

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。随着时间的推移,所有这些缩放操作都会导致您看到的 Artifact 。

要解决此问题,请将原始位图存储在不同的变量中(例如,private Bitmap originalImage;)并根据原始位图创建缩放后的位图。

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

关于java - 许多 drawBitmap 后图像质量变差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6723613/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com