Introduction
An open source extension that saves a component as an image.
Thanks to @Jerin_Jacob for the Convert component to image, I took inspiration from his extension.
Release date: 2022-03-23T03:30:00Z
Package name: com.gordonlu.viewutil.aix
Version: 2
Documentation
Event blocks
Failed
This event is fired when the extension has encountered an error. Possible reasons: quality is not a number between 0 and 100, wrong path, etc.
Parameters: error = text
Saved
This event is fired when the extension has saved the image at the path.
Parameters: path = text
Method blocks
SaveComponentAsImage
Saves the component as an image with the given path, compress format and the given quality. The quality parameter shall be a value between 0 and 100, and the path parameter shall be an absolute path.
The compressFormat parameter only accepts "JPEG" or "PNG". If not, then the file format should be "JPEG". The path should be something like: storage/emulated/0/Android/data/appinventor.ai_gordonlu0749.Save/filesimage.jpg.
Parameters: component = component, path = text, compressFormat = text, quality = number (int)
Property blocks
Jpg
A compressed format block.
Returns: "JPEG"
Png
A compressed format block.
Returns: "PNG"
Downloads
AIX:
com.gordonlu.viewutil.aix (7.0 KB)
AIA:
Save.aia (15.4 KB)
Open Source
Here you go.
package com.gordonlu.viewutil;
import android.app.Activity;
import android.content.Context;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;
import com.google.appinventor.components.runtime.AndroidViewComponent;
import android.view.View;
import android.graphics.Bitmap;
import java.io.FileOutputStream;
import android.graphics.Bitmap.CompressFormat;
@DesignerComponent(
version = 1,
description = "A non-visible extension to save a component as an image.",
category = ComponentCategory.EXTENSION,
nonVisible = true,
iconName = "https://docs.google.com/drawings/d/e/2PACX-1vQCI87PHLBF0jb8QWyYmIRQSjjNW3EFXf-qpsWCvBYkUQ9vEgPAB8SpxcMpblxNpbIYrjCjLrRLIU2c/pub?w=16&h=16")
@SimpleObject(external = true)
//Libraries
@UsesLibraries(libraries = "")
//Permissions
@UsesPermissions(permissionNames = "")
public class ViewUtil extends AndroidNonvisibleComponent {
//Activity and Context
private Context context;
private Activity activity;
public ViewUtil(ComponentContainer container){
super(container.$form());
this.activity = container.$context();
this.context = container.$context();
}
@SimpleFunction(description = "Saves the component as an image with the given path, compress format and the given quality.")
public void SaveComponentAsImage(AndroidViewComponent component, String path, String compressFormat, int quality) {
// https://stackoverflow.com/a/3527902/17802442
try {
View view = component.getView();
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
CompressFormat cp = CompressFormat.JPEG;
if (compressFormat == "PNG") {
cp = CompressFormat.PNG;
}
b.compress(cp, quality, new FileOutputStream(path));
Saved(path);
}
catch(Throwable e) {
Failed(e.getMessage());
}
}
@SimpleProperty(description = "A compress format block.")
public String Jpeg() {
return "JPEG";
}
@SimpleProperty(description = "A compress format block.")
public String Png() {
return "PNG";
}
@SimpleEvent(description = "This event is fired when the extension has failed to save the image.")
public void Failed (String error) {
EventDispatcher.dispatchEvent(this, "Failed", error);
}
@SimpleEvent(description = "This event is fired when the extension has saved the image.")
public void Saved (String path) {
EventDispatcher.dispatchEvent(this, "Saved", path);
}
}
The DownloadToAsd extension is here, in case if you want to get the ASD path.
Tests
All of these tests are successful in saving the image in storage/emulated/0/Download and the ASD (application-specific directory).
Companion:
- Android 11 API 30, Xiaomi 11 5G NE Lite.
APK:
-
Android 8.1 API 27, Google Pixel XL emulator.
-
Android 9 API 28, Google Pixel 5 emulator.
-
Android 11 API 30, Xiaomi 11 5G NE Lite.
-
Android 11 API 30, Google Pixel 2 emulator.
Requirements:
-
In Screen1 properties, set DefaultFileScope to Legacy.
-
You must have the write external storage permission (a.k.a. Files/photos and media).
-
For details on how to read external storage, please search the forum.
If you have any bugs, reply here.
Rate my extension!
- Good extension!
- Bad extension.
0 voters
Made with Niotron IDE.
Kindly PM me if you have any questions! Also, if you like my extension, please
like it! It takes some effort for me to make it...
Votes and likes tell me the general user feedback of my extension. If you read this extension, please take 20 seconds to drop by and give a like!
If you have any features that you want to add and you know the code, PM me or directly reply below using the button.
By downloading my extension, you agree the terms and conditions in my website
Gordon Lu