is there anybody know how to convert a HTML page to an image in Android AsyncTask or background thread?
Environment: Android Studio 2.0 Beta 5, Android Tablets with API version 18, 19
I have tried WebView control with two solutions but all failed.
Solution 1: Javascript
It doesn't work, getDrawingCache(true) always returns null.
public void generateImage()
{
final WebView mWebView = new WebView(this);
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mWebView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);
mWebView.setInitialScale(150);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setDrawingCacheEnabled(true);
mWebView.addJavascriptInterface(new JavaScriptInterface(mWebView), "Android");
String html = "<html><body onload=\"Android.captureImage()\">hello world<p>bbb</p></body></html>";
mWebView.loadDataWithBaseURL("", html, "text/html", "utf-8", "");
}
public class JavaScriptInterface
{
private WebView mWebView;
public JavaScriptInterface(WebView webView) {
mWebView = webView;
}
#JavascriptInterface
public void captureImage()
{
Bitmap b = mWebView.getDrawingCache(true);
if(b==null){
System.out.println("... b is null");
return;
}
System.out.println("... height "+b.getHeight()+" width "+b.getWidth());
}
}
Solution 2: WebViewClient + PictureListener
This one works on Android API 19. But on Android API 18, the callback "onNewPicture" is never get called.
public void generateImage()
{
final WebView mWebView = new WebView(this);
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mWebView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);
mWebView.setInitialScale(150);
mWebView.getSettings().setLoadWithOverviewMode(true);
String html = "<html><body>hello world<p>bbb</p></body></html>";
mWebView.loadDataWithBaseURL("", html, "text/html", "utf-8", "");
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
System.out.println("............ onPageFinished");
super.onPageFinished(view, url);
view.clearCache(true);
}
});
mWebView.setPictureListener(new WebView.PictureListener() {
#Override
public void onNewPicture(WebView view, Picture picture)
{
if (picture == null) {
return;
}
Picture pic = mWebView.capturePicture();
if(pic==null){
System.out.println("............ pic is null");
return;
}
System.out.println("onNewPicture............ width ["+pic.getWidth()+"] hieght ["+pic.getHeight()+"]");
final Bitmap bm = Bitmap.createBitmap(pic.getWidth(), pic.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
canvas.drawPicture(pic);
}
});
}
I can get image if I create WebView control in following way
final WebView mWebView = (WebView) findViewById(R.id.webview);
But I have to convert the html page string in an AsyncTask or a background thread. there is no UI at all. Is there anybody know how to implement it?
Any help is appreciated.
first set layout parameter for your WebView, second you should call Webview.measure and WebView.layout methods then draw cache on a bitmap:
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(final WebView view, String url) {
return false;
}
#Override
public void onPageFinished(final WebView view, String url) {
Log.i("HTML", "page finished loading " + url);
view.measure(View.MeasureSpec.makeMeasureSpec(512, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
final Bitmap bmp = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bmp);
canvas.drawBitmap(view.getDrawingCache(), 0, 0, new Paint());
// bitmap is ready
}
);
IMPORTANT TIP: make sure your WebView height and width isn't zero.
Related
I'm trying to set user's image and name in the action bar like so:
I'm not using a toolbar. The code:
if (receiverImageURL == null || receiverImageURL.trim().isEmpty()) {
final Bitmap circleLetterTile = tileProvider.getCircularLetterTile(receiverFullName);
getSupportActionBar().setIcon(new BitmapDrawable(getResources(), circleLetterTile));
setTitle(" " +StringUtils.capitalizeFully(receiverFullName));
} else {
Glide.with(this).asBitmap().load(receiverImageURL).into(new CustomViewTarget<ImageView, Bitmap>(???????) {
#Override
protected void onResourceCleared(#Nullable Drawable placeholder) {
}
#Override
public void onLoadFailed(#Nullable Drawable errorDrawable) {
final Bitmap circleLetterTile = tileProvider.getCircularLetterTile(receiverFullName);
getSupportActionBar().setIcon(new BitmapDrawable(getResources(), circleLetterTile));
setTitle(" " +StringUtils.capitalizeFully(receiverFullName));
}
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
final Bitmap circleAvatarBitmap = tileProvider.getCircularImage(resource);
getSupportActionBar().setIcon(new BitmapDrawable(getResources(), circleAvatarBitmap));
setTitle(" " +StringUtils.capitalizeFully(receiverFullName));
}
});
}
Which works if the user does not have an image (first if statement). But I have the following questions:
When using Glide, I need to pass the ImageView id into the ????? place but I'm not sure how to get.
I really don't like the space that I used in the setTitle(" " +StringUtils.capitalizeFully(receiverFullName)); for mocking the margin (took from other similar topic).
What would be easiest way to fix those two issues?
With an ActionBar you can use:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setLogo(R.drawable.xxxx);
With a Toolbar:
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setLogo(R.drawable.xxxxx);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
I'm a newbie in programming. I want to build a QR Code Generator that the QR Code can be saved or downloaded.
Here's my code for the generator:
public class GeneratorActivity extends AppCompatActivity {
EditText text;
Button gen_btn;
ImageView image;
String text2Qr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_generator);
text = findViewById(R.id.text);
gen_btn = findViewById(R.id.gen_btn);
image = findViewById(R.id.image);
gen_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
text2Qr = text.getText().toString().trim();
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
try{
BitMatrix bitMatrix = multiFormatWriter.encode(text2Qr, BarcodeFormat.QR_CODE,200,200);
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
image.setImageBitmap(bitmap);
bitmap = ((BitmapDrawable) ImageView.getdrawable()).getBitmap();
}
catch (WriterException e){
e.printStackTrace();
}
}
});
}
}
I got a error that I cannot resolve method 'getdrawable()
anybody know how to fix this?
Here's the screenshot of the error: screenshot
get the drawable like from imageview like
Drawable myDrawable = imageView.getDrawable();
You can compare it with a drawable resource like
if(iv.getDrawable()==getResources().getDrawable(R.drawable.image1)){
//do work here
}
getDrawable
Return a drawable object associated with a particular resource ID and
styled for the specified theme.
You should pass OBJECT
bitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
FYI
Drawable drawable = image.getDrawable();
You already have a bitmap and you have set it to imageview. Why do you need this line
bitmap = ((BitmapDrawable) ImageView.getdrawable()).getBitmap();
The error is saying that there is no method called getDrawable() in the ImageView class.
I think you can use it Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);directly. may be not need bitmap = ((BitmapDrawable) image.getdrawable()).getBitmap();
You are getting drawable from empty imageview that will return null. for getting bitmap from drawble, try this method.
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
Hope it will help you!!
I need to do a screenshot from my WebView, or you can say, Convert html to Bitmap.
And I have a trouble with this task. view.postDelayd(new Runnable() { ... don't create a new Thread, where my capture picture is
private void Main {
WebView webView = new WebView(this.context); //init WebView
saveHtmlImage(webView); //running method for capture picture
}
private void saveHtmlImage(final WebView webView){
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
view.postDelayed(new Runnable() { //trouble here
#Override
public void run() {
Picture picture = webView.capturePicture();
Bitmap b = Bitmap.createBitmap( picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
picture.draw(c);
}
}, 100);
}
});
//set HTML code for WebView
webView.loadDataWithBaseURL(null, "<TABLE border=\"1\"\n" +
" summary=\"This table gives some statistics about fruit\n" +
" flies: average height and weight, and percentage\n" +
" with red eyes (for both males and females).\">\n" +
"<CAPTION><EM>A test table with merged cells</EM></CAPTION>\n" +
"<TR><TH rowspan=\"2\"><TH colspan=\"2\">Average\n" +
" <TH rowspan=\"2\">Red<BR>eyes\n" +
"<TR><TH>height<TH>weight\n" +
"<TR><TH>Males<TD>1.9<TD>0.003<TD>40%\n" +
"<TR><TH>Females<TD>1.7<TD>0.002<TD>43%\n" +
"</TABLE>", "text/html", "UTF-8", null);
}
When I don't use Runnable, Bitmap.createBitmap(...) give exception -
java.lang.IllegalArgumentException: width and height must be > 0.
When I'm using
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
intead
view.postDelayd(new Runnable() {
the method
webView.capturePicture();
return empty screenshot, but with correct width and height
Please help me.
Say What I'm doing wrong, or maybe give me another example of code that can convert html code to Bitmap Image.
Thank you in advance for your reply.
Just do a force to fit fullscreen and code a standard screenshot and convert to bitmap. If you need an example let me know.
I am using picasso library to load images from url to ImageView,
Picasso.with(activityContext).load(thumbnailurl)
.into(imageViewReference);
Can I set background image of ImageView (Not the source Image), using Picasso.
You can use callback of picasso.However you can't use setBackgroundResource because it's always takes int as parameter and you will get bitmap in return from picasso.
Picasso.with(getContext()).load(url).into(new Target() {
#Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Drawable d = new BitmapDrawable(getResources(),bitmap);
imageView.setBackground(d);
}
#Override public void onBitmapFailed(Drawable errorDrawable) { }
#Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
});
private Bitmap overlay(Bitmap bitmap1, Bitmap bitmap2) {
Bitmap bmOverlay = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(), bitmap1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bitmap1, new Matrix(), null);
canvas.drawBitmap(bitmap2, new Matrix(), null);
return bmOverlay;
}
if you have to set one image over another the same task i have done by using transparent image from drawable and another one is getting from sdcard,using this code it works,you have to just pass your images bitmap in this method()...
Just two things, is this a good simple way to grab images? also when i do try it on the android AVD nothing gets displayed on screen as well as in log_cat, no errors or crashes. Here is my code:
public class MainActivity extends Activity {
Bitmap bitmap = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
bitmap = getBitmap("https://twimg0-a.akamaihd.net/profile_images/2275552571/image_normal.jpg");
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(bitmap);
}catch(Exception e){
}
}
public Bitmap getBitmap(String bitmapUrl) {
try {
URL url = new URL(bitmapUrl);
return BitmapFactory.decodeStream(url.openConnection().getInputStream());
}catch(Exception ex) {return null;}
}
}
try : http://code.google.com/p/android-imagedownloader/ .
You can download remote images synchronously, Asynchronously, etc. it works really good
ImageDownloader imageDownloader = new ImageDownloader();
imageDownloader.setMode(ImageDownloader.Mode.CORRECT);
ImageView imageView = (ImageView) rowView.findViewById(R.id.picture);
imageView.setLayoutParams(new GridView.LayoutParams(140, 140));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(4, 4, 4, 4);
List<ImageSize> images = this.pictures.get(position).getImages();
imageDownloader.download(images.get(images.size()-3).getSource(), imageView);
It doesn't work because your picture's url starts with HTTPS. Try to use HttpGet. Something like that.