I am working on a project that uses a parse server. It works like tinder and allows users to download and display names and images of other users nearby.
It works, accept for one bug where the names and the images do not match up correctly when displayed in the app.
The app initially downloads and creates an array of local users, and this works fine.
I then download their images using the following code:
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereWithinKilometers("location", parseCustLocation, searchRadius);
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(final List<ParseUser> objects, ParseException e) {
if (e==null){
Log.d("state", "215 query successful");
if (objects.size()>0) {
for (final ParseUser user : objects){
Log.d("state", "231"+user.getUsername());
//TextView text = (TextView) findViewById(R.id.Name);
Users.add(user);
sUsers.add((String) user.get("Name"));
locations.add((ParseGeoPoint) user.get("location"));
parseFiles.add((ParseFile) user.get("image"));
}
for (ParseFile file : parseFiles) {
file.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Log.d("state", "174 we've got data");
Bitmap bmp = BitmapFactory.decodeByteArray(data,0,data.length);
bitmaps.add(bmp);
if (sUsers.size()==bitmaps.size()){
swipeAdapter.updateData(sUsers,bitmaps);
}
}
}
});}
As far as I can tell, I think the issue is with the lines
Bitmap bmp = BitmapFactory.decodeByteArray(data,0,data.length);
bitmaps.add(bmp);
as, for example, when I run the debugger I have two arrays as follows (the bitmapFactory seems to be putting the bitmaps in any part of the bitmap[]):
sUsers[0] = "Billy",
sUsers[1] = "Sarah",
sUsers[2] = "Jim",
bitmaps[0] = Sarahs image,
bitmaps[1] = Jims image,
bitmaps[2] = Billys image
When obviously I need
bitmaps[0] = Billys image,
bitmaps[1] = Sarahs image,
bitmaps[2] = Jims image,
NOTE:
The bitmaps seem to be in the correct order if I run the app step by step using the debugger.
file.getDataInBackground is an async callback, so the first data retrieved will be the first added to bitmaps array,
You can use an Hashmap each key will be the user objectId and the key the data of your user.
Map<String, data> map = new HashMap<String, data>(); // your Hashmap
Thanks Julien, I managed to get it working correctly but with a very crude workaround using lots of nested Async tasks:
parseFiles.get(0).getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(0, bmp);
parseFiles.get(1).getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(1, bmp);
parseFiles.get(2).getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(2, bmp);
parseFiles.get(3).getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(3, bmp);
parseFiles.get(4).getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(4, bmp);
parseFiles.get(5).getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e==null){
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
//bitmaps.add(bmp);
bitmaps.add(5, bmp);
if (sVenueUsers.size()==bitmaps.size()){
swipeAdapter.updateData(sUsers, bitmaps);
}
}
}
});
}
}
});
}
}
});
}
}
});
}
}
});
}
}
});
I tried your Hashmap idea, but got the message that data was an unrecognised class. I shall try working it through later.
Related
Is it possible to add an image to the PDF document? My layout has one (Button) and one (ImageView), I would like that when I click (Button), it will open the Gallery to select the image, show it in (ImageView) and add it to the PDF document, as if it were a generator curriculum, thank you in advance.
*Using com.itextpdf:itextg:5.5.10
here is the complete code of what you wanted. Try this and let me know.
In the onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_to_pdf);
imageView = findViewById(R.id.imageView);
galleryBtn = findViewById(R.id.gallery);
convertBtn = findViewById(R.id.convert);
galleryBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "PDF_" + timeStamp + "_";
File storageDir = getAlbumDir();
try {
pdfPath = File.createTempFile(
imageFileName, /* prefix */
".pdf", /* suffix */
storageDir /* directory */
);
} catch (IOException e) {
e.printStackTrace();
}
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(photoPickerIntent, GALLERY_INTENT);
}
});
convertBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (bitmap == null) {
Toast.makeText(ImageToPDF.this, "Please select the image from gallery", Toast.LENGTH_LONG).show();
} else {
convertToPDF(pdfPath);
}
}
});
}
Create a directory for PDF file:
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStorageDirectory()
+ "/dcim/"
+ "Image to pdf");
if (!storageDir.mkdirs()) {
if (!storageDir.exists()) {
Log.d("CameraSample", "failed to create directory");
return null;
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
On camera activity intent result:
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_INTENT) {
if (resultCode == Activity.RESULT_OK && data != null) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
if (selectedImage != null) {
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String imagePath = cursor.getString(columnIndex);
bitmap = BitmapFactory.decodeFile(imagePath);
imageView.setImageBitmap(bitmap);
cursor.close();
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.e("Canceled", "Image not selected");
}
}
}
Now code to convert image to PDF and save to the directory:
private void convertToPDF(File pdfPath) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
PdfDocument pdfDocument = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(width, height, 1).create();
PdfDocument.Page page = pdfDocument.startPage(pageInfo);
Canvas canvas = page.getCanvas();
Paint paint = new Paint();
paint.setColor(Color.parseColor("#ffffff"));
canvas.drawPaint(paint);
bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
paint.setColor(Color.BLUE);
canvas.drawBitmap(bitmap, 0, 0, null);
pdfDocument.finishPage(page);
try {
pdfDocument.writeTo(new FileOutputStream(pdfPath));
Toast.makeText(ImageToPDF.this, "Image is successfully converted to PDF", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
pdfDocument.close();
}
In Asynctask,either the progress bar is working or file is uploading successfully.
COMMENT2 line upload file properly when we write before the COMMENT1 line but progress bar is not working.
But if we write COMMENT2 after COMMENT1 then we face ERROR code 500(Syntax error) and uploading failed but progress bar
works properly.
private class AsyncCaller extends AsyncTask<String, Integer, String> {
int bytesRead, bytesAvailable, bufferSize = 1024,progress;
byte[] buffer;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setMessage("Uploading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setCancelable(false);
mProgressDialog.setProgress(0);
mProgressDialog.setMax(100);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
// connection();
FTPClient con = null;
try
{
con = new FTPClient();
con.connect(FTP_HOST);
if (con.login(FTP_USER, FTP_PASS))
{
con.enterLocalActiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
con.changeWorkingDirectory("/uploads/school-staging/files/");
String data = FilePath;
final DataOutputStream out = new DataOutputStream(con.getOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(data));
int bufferSize=1024;
byte[] buffer = new byte[bufferSize];
// Read file
bytesRead = in.read(buffer, 0, bufferSize);//COMMENT 1
progress=0;
System.out.println("BYTE READ="+bytesRead);
while (bytesRead > 0)
{
progress+=bytesRead;
System.out.println("PROGRESS="+progress);
out.write(buffer, 0, bytesRead);
bytesAvailable = in.available();
publishProgress((int)((progress*100)/(file.length())));
bufferSize = Math.min(bytesAvailable, bufferSize);
bytesRead = in.read(buffer, 0, bufferSize);
}
boolean result = con.storeFile(FileName, in);//COMMENT 2
int code= con.getReplyCode();
System.out.println("CODE="+code);
in.close();
publishProgress(100);
if (result) Log.v("upload result", "succeeded");
System.out.println("RESULT="+result);
con.logout();
con.disconnect();
}
}
catch (Exception e)
{
e.printStackTrace();
}
return "ok";
}
#Override
public void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
mProgressDialog.setProgress(values[0]);
}//end of onProgressUpdate
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
connection();
mProgressDialog.dismiss();
}
I've faced similar problem. The reason for this seems to be that the ui code in onPreExecute() doesnt get to render by android system, and code in doInBackground() occupies the cpu. You can dismiss the dialog in onPostExecute() though...
You'd have to show the progress dialog before creating AsyncCaller, pass the progress dialog to AsyncCaller and you can dismiss it in onPostExecute().
ProgressDialog pd = new ProgressDialog(getActivity());
pd.setTitle("title string");
pd.setIndeterminate(true);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.show();
new AsyncCaller(getActivity(), pd).execute(params);
in onPostExecute():
if (pd != null && pd.isShowing())
pd.dismiss();
This is a part of my onActivity Result code. What i want to do is make a bitmap variable that i can modify everytime i press a button instead of modifying the ImageView(imagen) and not saving the changes that happen to the image.
When i try to change the btp_tmp variable inside the onClick code of the button it throws an error about btp_tmp being in an inner class and must be made final.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap btp_img = null;
InputStream in_stream;
Bitmap btp_tmp = null;
if (resultCode == Activity.RESULT_OK && requestCode == RCode)
{
//ARXIKO IMAGE
try {
if (btp_img != null) {
btp_img.recycle();
}
in_stream = getContentResolver().openInputStream(
data.getData());
btp_img = BitmapFactory.decodeStream(in_stream);
in_stream.close();
btp_tmp = btp_img;
imagen.setImageBitmap(btp_img);
//btn_seleccion.setText(getResources().getString(R.string.modifa));
} catch (IOException e) {
e.printStackTrace();
}
//NEGATIVE
//final boolean test = false;
final Bitmap finalBtp_img1 = btp_tmp;
//if (test == false){}
btp_tmp = btp_img;
Neg_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//imagen.setImageBitmap(invert(finalBtp_img));
Negative neg = new Negative();
imagen.setImageBitmap(neg.invert(finalBtp_img1));
btp_tmp = neg.invert(finalBtp_img1);
}
});
//UNDO
final Bitmap finalBtp_imgUndo = btp_img;
eraser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imagen.setImageBitmap(finalBtp_imgUndo);
}
});
I found the solution. The mistake i was doing is that i didn't declare the temporary variable in the Main Activity Class, so i got an error everytime i used the variable in the OnActivity part of the code.
Rookie mistake for sure.
I found some examples for how to extract images from PDF using iText. But what I am looking for is to get the images from PDF by coordinates.
Is it possible? If yes then how it can be done.
Along the lines of the iText example ExtractImages you can extract code like this:
PdfReader reader = new PdfReader(resourceStream);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
ImageRenderListener listener = new ImageRenderListener("testpdf");
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
parser.processContent(i, listener);
}
The ImageRenderListener is defined like this:
class ImageRenderListener implements RenderListener
{
final String name;
int counter = 100000;
public ImageRenderListener(String name)
{
this.name = name;
}
public void beginTextBlock() { }
public void renderText(TextRenderInfo renderInfo) { }
public void endTextBlock() { }
public void renderImage(ImageRenderInfo renderInfo)
{
try
{
PdfImageObject image = renderInfo.getImage();
if (image == null) return;
int number = renderInfo.getRef() != null ? renderInfo.getRef().getNumber() : counter++;
String filename = String.format("%s-%s.%s", name, number, image.getFileType());
FileOutputStream os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
PdfDictionary imageDictionary = image.getDictionary();
PRStream maskStream = (PRStream) imageDictionary.getAsStream(PdfName.SMASK);
if (maskStream != null)
{
PdfImageObject maskImage = new PdfImageObject(maskStream);
filename = String.format("%s-%s-mask.%s", name, number, maskImage.getFileType());
os = new FileOutputStream(filename);
os.write(maskImage.getImageAsBytes());
os.flush();
os.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
As you see the ImageRenderListener method renderImage retrieves an argument ImageRenderInfo. This arguments has methods
getStartPoint giving you a vector in User space representing the start point of the xobject and
getImageCTM giving you the coordinate transformation matrix active when this image was rendered. Coordinates are in User space.
The latter gives you the information which exact manipulation on a 1x1 user space unit square are used to actually draw the image. As you are aware, an image may be rotated, stretched, skewed, and moved (the former method actually extracts its result from the matrix from the "moved" information).
After taking a picture in my app I want to get the image (by it's path).
I see lots of examples on how to get an image, the only problem is that it no longer is possible doing it by using Connector.open() since Connector is deprecated now.
What to use instead?
conn = (FileConnection)Connector.open("file:///SDCard/BlackBerry/pictures/" + picture);
try {
InputStream input = null;
input = fconn.openInputStream();
int available = 0;
available = input.available();
int fSz = (int)fconn.fileSize();
byte[] data = new byte[fSz];
input.read(data, 0, fSz);
image = EncodedImage.createEncodedImage(data,0,data.length);
bkBitmap = image.getBitmap();
} catch(ControlledAccessException e) {
pLog = "*** Problem Accessing image file:" + e;
EventLogger.logEvent( GUID, pLog.getBytes() );
}
Thanks!
Try this code:
public class LoadingScreen extends MainScreen
{
public LoadingScreen()
{
setTitle("Loading Screen");
createGUI();
}
private void createGUI()
{
BitmapField bitmapField=new BitmapField(getTheImage());
add(bitmapField);
}
private Bitmap getTheImage()
{
Bitmap bitmap=null,scaleBitmap=null;
InputStream inputStream=null;
FileConnection fileConnection=null;
try
{
fileConnection=(FileConnection) Connector.open("file:///SDCard/BlackBerry/pictures/"+"background.png");
if(fileConnection.exists())
{
inputStream=fileConnection.openInputStream();
byte[] data=new byte[(int)fileConnection.fileSize()];
data=IOUtilities.streamToBytes(inputStream);
inputStream.close();
fileConnection.close();
bitmap=Bitmap.createBitmapFromBytes(data,0,data.length,1);
//You can return this bitmap otherwise, after this you can scale it according to your requirement; like...
scaleBitmap=new Bitmap(150, 150);
bitmap.scaleInto(scaleBitmap, Bitmap.FILTER_LANCZOS);
}
else
{
scaleBitmap=Bitmap.getBitmapResource("noimage.png");//Otherwise, Give a Dialog here;
}
}
catch (Exception e)
{
try
{
if(inputStream!=null)
{
inputStream.close();
}
if(fileConnection!=null)
{
fileConnection.close();
}
}
catch (Exception exp)
{
}
scaleBitmap=Bitmap.getBitmapResource("noimage.png");//Your known Image;
}
return scaleBitmap;//return the scale Bitmap not the original bitmap;
}
}
I got like this below Image: