I wanted to convert a TIFF to JPEG in Android Studio. I got the error message
Error:(116, 15) error: cannot find symbol class SeekableStream
Error:(116, 38) error: cannot find symbol class FileSeekableStream
Error:(117, 17) error: cannot find symbol class TIFFDecodeParam
Error:(118, 17) error: cannot find symbol class ImageDecoder
Error:(118, 36) error: cannot find symbol variable ImageCodec
Error:(119, 17) error: cannot find symbol class RenderedImage
I found that I need to use javax.media.jai. How can I import the lib to Android Studio. I am new to Android Studio.
Thanks in advance.
L
The quick answer: You can't. JAI and everything javax.media.jai relies heavily on Java2D and the java.awt and java.awt.image packages, which is not part of the Android platform.
If you want to read a TIFF on Android, I think you can use libTIFF (the C library) and Android NDK.
NOTE: I'm assuming you want to create a program to convert a TIFF to a JPEG. If you just want to convert a specific file for use in Android Studio, this question is off-topic for StackOverflow. You should instead ask how to convert the image on SuperUser (though I'm sure you'll find this question is already answered).
https://letsmakeandroidapp.wordpress.com/learn-reading-binary-files-decode-tiff-images/
Check above link for full code view but code snippet i will give below:-
package com.tif;
import android.os.*;import android.content.*;import android.app.*;import android.widget.*;import android.view.*;
import android.view.View.*;import android.graphics.*;import java.io.*;import java.util.*;import android.util.*;
import java.lang.*;import java.nio.*;import java.nio.channels.*;
public class Main extends Activity
{
private static final int CLEAR_CODE = 256;
private static final int EOI_CODE = 257;
long bytesCount=0L;
ScrollView sv;TextView tv;ImageView iv;
List intList;
long[] stripOffs,stripBytes;
byte[] bytes,ubytes,bmpBytes;
ByteBuffer bBuff;
BitBuffer bitBuff;
int entries,type,tag;
long count,value,ifd,stripAt,stripCount,stripBytesAt,rows,cols;
String txt="Null",path="",decompressed="";
String[] info= {"width","length","bitsPerSample","Compression","PhotometricInterpretation","Fil lOrder","StripOffsets","SamplesPerPixel","RowsPerStrip"
,"StripBytes","XResolution","YResolution","PlanarConfig","ResolutionUnit","extra ","NextIFD"};
Bitmap bmp=null;
class DotsView extends View
{
int i = 0;Bitmap bmp;Canvas cnv;Rect bounds;Paint p;int width,height;
int alfa,red,green,blue;
public DotsView(Context context ,int width ,int height)
{
super(context);
this.width = width;
this.height = height;
bmp = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
cnv = new Canvas(bmp);
bounds = new Rect(0 , 0, width,height);
p = new Paint();
}
#Override
protected void onDraw(Canvas c)
{
for(int i=0;i<width;i++)
for(int j=0;j<height;j++)
{
for(int pix=0;pix<3;pix++)
{
if(pix==0)blue=bmpBytes[i+j+pix];
if(pix==1)green=bmpBytes[i+j+pix];
if(pix==2)red=bmpBytes[i+j+pix];
}
p.setColor( Color.argb(255, red,green,blue) );
cnv.drawPoint(i,j, p);
}
c.drawBitmap(bmp, null, bounds , null);
invalidate();
}
}
public int myShort(short sh)
{ int i;
ByteBuffer shortBuff=ByteBuffer.allocate(4);
shortBuff.order(ByteOrder.BIG_ENDIAN);shortBuff.putShort(sh);shortBuff.rewind();
shortBuff.order(ByteOrder.LITTLE_ENDIAN);sh=shortBuff.getShort();
if(sh<0)i=(int)(sh+32768); else i=(int)sh;
return i;
}
public long myInt(int i)
{ long l=0L;
ByteBuffer intBuff=ByteBuffer.allocate(4);
intBuff.order(ByteOrder.BIG_ENDIAN);intBuff.putInt(i);intBuff.rewind();
intBuff.order(ByteOrder.LITTLE_ENDIAN); i=intBuff.getInt();
if(i<0)l=(long)(i+2147483648L); else l=(long)i;
return l;
}
public String tagInfo(int tag)
{ int i=0;
switch(tag)
{case 256: i=0;break;case 257: i=1;break;case 258: i=2;break;case 259: i=3;break;case 262: i=4;break;case 266: i=5;break;
case 273: i=6;break;case 277: i=7;break;case 278: i=8;break;case 279: i=9;break;case 282: i=10;break;case 283: i=11;break;
case 284: i=12;break;case 296: i=13;break;case 1496: i=14;break;case 0: i=15;break;
}
return info[i];
}
public void extractTif()
{
String taginfo="";String strVal="";
FileInputStream fis;BufferedInputStream bis;DataInputStream dis;
path=Environment.getExternalStorageDirectory().getPath();
path=path+"/DCIM"+"/kpd.tif";
try {
fis=new FileInputStream(path);bis=new BufferedInputStream(fis);dis=new DataInputStream(bis);
dis.skip(4);ifd=myInt(dis.readInt());
txt="TIFF-IFD: "; txt=txt+ifd;
dis.skip(ifd-8); entries=myShort(dis.readShort());
txt=txt+"\nNo.OfEntries="+entries;
for(int i=0;i<=entries;i++)
{ tag=myShort( dis.readShort() );taginfo=tagInfo(tag);
type=myShort( dis.readShort() );count=myInt( dis.readInt() );value=myInt( dis.readInt() );
if(type==3)strVal="Value="; else strVal="Offset=";
if( strVal.equals("Offset=") )
{
if( taginfo.equals("StripOffsets") ){stripAt=value;stripCount=count;}
if( taginfo.equals("StripBytes") ){stripBytesAt=value;}
}
if( taginfo.equals("width") ){cols=value;}
if( taginfo.equals("length") ){rows=value;}
txt=txt+"\ntag="+tag+" "+tagInfo(tag)+",type="+type+",count="+count+strVal+value;
}
dis.close();bis.close();fis.close();
}catch(Exception e) {txt=txt+"\nerror="+e.toString();}
txt=txt+"\nNo.OfStrips="+stripCount+",array of strip locations at: "+stripAt+" and array of bytesPerStrip at "+stripBytesAt ;
extractBMP();
}
public void extractBMP()
{try{ File f=new File(path);RandomAccessFile raf=new RandomAccessFile(f,"r");
raf.seek(stripAt);stripOffs=new long[(int)stripCount];
txt=txt+"\nArray Of Image Offsets=";
for(int i=0;i<stripCount;i++){stripOffs[i]=myInt( raf.readInt() ); txt=txt+","+stripOffs[i]; }
raf.seek(stripBytesAt); stripBytes=new long[(int)stripCount];
txt=txt+"\nArray Of Strip Bytes =";
for(int i=0;i<stripCount;i++){stripBytes[i]=myInt(raf.readInt()); txt=txt+","+stripBytes[i];bytesCount+=stripBytes[i];}
txt=txt+stripBytes;
bBuff =ByteBuffer.allocate((int)(rows*cols*3));
for(int i=0;i<stripCount;i++)
{
bytes =new byte[(int)stripBytes[i]];
raf.seek(stripOffs[i]);
raf.read(bytes);
bBuff.put(lzwUncompress(bytes));
bytes=null;
}
txt=txt+"\nBuffered Image Bytes Size="+bBuff.position();
bBuff.rewind();
bmpBytes=new byte[bBuff.remaining()];
bmpBytes=bBuff.array();
txt=txt+"\nCount of bmpBytes="+bmpBytes.length;
bmp=BitmapFactory.decodeByteArray(bmpBytes,0,bmpBytes.length);
SystemClock.sleep(5000);
txt=txt+"Bitmap Object, bmp="+bmp;
if(bmp!=null){iv.setImageBitmap(bmp);sv.addView(iv);}
raf.close();
}catch(Exception e){txt=txt+"\nerror="+e.toString();}
}
public void lzw()
{
//String[] table=new String[4096];
byte b;char ch;String s;String pre="";short sh;
//List strTable=Arrays.asList(table);
//for(int i=0;i<255;i++)table[i]=Character.toString((char)i);
for(int i=0;i<100;i++)
{
b=bytes[i];
if(b<0)sh=(short)(128+b);
else sh=(short)b;
//ch=(char)b;
s=String.valueOf(sh);
//s=s+pre;
//if(strTable.contains(s)){pre=s;}
//else{ }
txt=txt+"Byte No."+i+"="+s+" ";
}
}
public void onCreate(Bundle bnd)
{
super.onCreate(bnd);
extractTif();
//sv=new ScrollView(this);
//tv=new TextView(this);
//iv=new ImageView(this);
//tv.setTextSize(7);
//sv.addView(tv);
//sv.addView(iv);
//tv.setText(txt);
//setContentView(sv);
Point res=new Point(); getWindowManager().getDefaultDisplay().getSize(res);
DotsView myView = new DotsView(this,res.x,res.y);
setContentView(myView);
}
Related
I use ListChangeListener to listen to changes in Tab Pane.
private final TabPane tabBar = new TabPane();
...
tabBar.getTabs().addListener(this::tabsChanged);
I'm trying to listen to tab move events with the following code:
private void tabsChanged(ListChangeListener.Change<? extends Tab> change) {
while (change.next()) {
if (change.wasPermutated()) {
for (int i = change.getFrom(); i < change.getTo(); i++) {
System.out.println(i + " -> " + change.getPermutation(i));
}
}
}
}
As JavaFX documentation says:
In order to get the new position of an element, you must call:
change.getPermutation(oldIndex). Returns: the new index of the same
element.
But in my case change.getPermutation(i) always returns just i.
For example, I have 4 tabs.
Their indexes are: 0, 1, 2, 3.
Then I move the 4th tab to the first position.
I expect the following output:
0 -> 1
1 -> 2
2 -> 3
3 -> 0
But I get:
0 -> 0
1 -> 1
2 -> 2
3 -> 3
How can I make it work as I need?
As already noted in the comments: the behavior you observe is a bug just reported as JDK-8278062 - the doc and your expectation based on the doc is correct, the notification (implemented in the internal class TabObservableList) is wrong.
Normally, if we want to find the newIndex, a listChangeListener would do something like:
for (int oldIndex = c.getFrom(); oldIndex < c.getTo(); ++oldIndex) {
int newIndex = c.getPermutation(oldIndex);
...
}
To work around the issue, we could manually keep a copy of the tabs, lookup the tab at the old index and find its new index in the re-ordered tabs:
for (int oldIndex = c.getFrom(); oldIndex < c.getTo(); ++oldIndex) {
Tab tab = copy.get(oldIndex);
int newIndex = c.getList().indexOf(tab);
...
}
// update the copy
Or we could have some fun and implement a TransformationList around the original tabs that does the work for us :) It jumps in when it detects a permutation and fires the correct notification. Note that the only internal class used below is SourceChangeAdapter, we either need to relax encapsulation or c&p its content (it is doing nothing but pass on notifications on behalf of the wrapper)
public class TabObservableListWrapper extends TransformationList<Tab, Tab> {
// copy of source used to build the correct permutation
private ObservableList<Tab> copy = FXCollections.observableArrayList();
public TabObservableListWrapper(ObservableList<Tab> source) {
super(source);
updateCopy();
}
#Override
protected void sourceChanged(Change<? extends Tab> c) {
// TBD: cope with a change that has
// - a mixture of permutation and other subchanges
// - multiple subchanges of type permutation
boolean isPermutation = false;
// check if the change is a permutation
while (c.next()) {
if (c.wasPermutated()) {
isPermutation = true;
break;
}
}
c.reset();
if (isPermutation) {
beginChange();
updatePermutation(c);
endChange();
} else {
// assuming other change type notifications are correct, just delegate
fireChange(new SourceAdapterChange<>(this, c));
}
// keep copy sync'ed to source
updateCopy();
}
/**
* Converts the incorrect permutation notification from source
* into a correct one and let super fire the appropriate change.
*
* Note: this method must be called inside a begin/endChange block.
* #param c a change with a single subChange of type wasPermutated
*/
private void updatePermutation(Change<? extends Tab> c) {
c.next();
int from = c.getFrom();
int to = c.getTo();
int permSize = to - from;
int[] perm = new int[permSize];
// fill the perm
for(int i = 0; i < permSize; i++) {
int oldIndex = from + i;
Tab tab = copy.get(oldIndex);
perm[i] = c.getList().indexOf(tab);
}
nextPermutation(from, to, perm);
}
// keep copy sync'ed
private void updateCopy() {
copy.setAll(getSource());
}
// implement public methods by delegating 1:1 to source
#Override
public int getSourceIndex(int index) {
return index;
}
#Override
public int getViewIndex(int index) {
return index;
}
#Override
public Tab get(int index) {
return getSource().get(index);
}
#Override
public int size() {
return getSource().size();
}
}
To use, wrap it around a tabPane's tab list and listen to the wrapper instead of directly to original list, something like:
TabObservableListWrapper wrapper = new TabObservableListWrapper(tabPane.getTabs());
wrapper.addListener((ListChangeListener<Tab>)change -> {
while (change.next()) {
if (change.wasPermutated()) {
System.out.println("from wrapper:");
for (int oldIndex = change.getFrom(); oldIndex < change.getTo(); oldIndex++) {
System.out.println(oldIndex + " -> " + change.getPermutation(oldIndex));
}
}
}
});
I'm creating line chart using Java FX. On update, I have a list of checkbox to select or deselect the series of linechart. When all are deselected but tick points or animated tick points are there and so on by doing the same thing again or adding new data for line chart it is same. I'm unable to add images to make it easier for you. Please do some help.
private static void printChartAnalysis(analysisResults r){
clearAnalsisChartData();
int [][]analysisResult=r.getAnalysisResult();
ArrayList<String> versionss=r.getVersions();
int k=0;
for(String x:versionss){
String z=new String();
for(int i=0;i<x.length();i++){
if(Character.isDigit(x.charAt(i))){
z+=x.charAt(i);
}
}
dataLOC.add(new XYChart.Data(z,(int)analysisResult[k][0]));
dataComm.add(new XYChart.Data(z,(int)analysisResult[k][1]));
dataCond.add(new XYChart.Data(z,(int)analysisResult[k][2]));
dataLoops.add(new XYChart.Data(z,(int)analysisResult[k][3]));
dataMem.add(new XYChart.Data(z,(int)analysisResult[k][4]));
k++;
}
seriesLOC.setData(dataLOC);
seriesCond.setData(dataCond);
seriesComm.setData(dataComm);
seriesLoop.setData(dataLoops);
seriesMem.setData(dataMem);
lineChart.getData().setAll(seriesLOC,seriesComm,seriesCond,seriesLoop,seriesMem);
lineChart.setTitle("Line Chart for "+r.getSoftwareName());
for (int i = 0; i < names.length; i++) {
final CheckBox cb = cbs[i];
cb.setSelected(true);
}
}
private static void printChartCost(cocomoResults est){
clearAnalsisChartData();
clearCostChartData();
for(COCOMO cost:est.getVersionsResult()){
String version=cost.getVersion();
String z=new String();
for(int i=0;i<version.length();i++){
if(Character.isDigit(version.charAt(i))){
z+=version.charAt(i);
}
}
dataEffort.add(new XYChart.Data(z,(int)cost.getEffort()));
dataDura.add(new XYChart.Data(z,(int)cost.getDuration()));
dataStaff.add(new XYChart.Data(z,(int)cost.getStaff()));
dataProd.add(new XYChart.Data(z,(int)cost.getProductivity()));
}
seriesEffort.setData(dataEffort);
seriesDura.setData(dataDura);
seriesStaff.setData(dataStaff);
seriesProd.setData(dataProd);
lineChart.getData().setAll(seriesEffort,seriesDura,seriesStaff,seriesProd);
}
private static void clearAnalsisChartData(){
lineChart.getData().removeAll(seriesLOC);
lineChart.getData().removeAll(seriesComm);
lineChart.getData().removeAll(seriesCond);
lineChart.getData().removeAll(seriesLoop);
lineChart.getData().removeAll(seriesMem);
dataLOC.clear();
dataLoops.clear();
dataComm.clear();
dataCond.clear();
dataMem.clear();
}
As far as I understood
cb.setOnAction(event -> {
if (lineChart.contains(*NAME_OF_YOUR_ELEMENT*))
lineChart.remove(*NAME_OF_YOUR_ELEMENT*)
else
lineChart.remove(*NAME_OF_YOUR_ELEMENT*)
});
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I have to make a program that interacts with the user interface that ask a user for a number and a base to convert to binary, hex, or octo. I made a program that works but when the user types in "0 0", it is suppose to terminate and end the program. My program on the other hand doesn't do that but keep going in the while loop.
Here is the code:
import java.util.*; //for Scanner
public class BaseConversionApp {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
String combo = numbers(console);
while(combo != "0 0") {
if(combo.length() > 0) { //breaks the string into integers to do math to it
Scanner s = new Scanner(combo);
int count = s.nextInt();
int countSecond = s.nextInt();
s.close();
conversion(count,countSecond);
System.out.println();
//now if it goes 0 0 or
String again = numbers(console);
// conversion(count,countSecond);
}
}
//prompts the user for two numbers and checks if the bases are 16, 8, 2.
public static String numbers(Scanner console) {
String combination = "";
String nothing = "0 0";
System.out.print("Enter an integer and the new base: ");
int integer = console.nextInt();
int base = console.nextInt();
if(base == 16 || base == 2 || base == 8) {
combination = integer + " " + base;
return combination;
} else if (base == 0 && integer == 0){
System.out.println("Good bye!");
return nothing;
} else {
System.out.println("Sorry, that is an invalid base. Please enter 2, 8, or 16
only.");
}
return "";
}
//converts the integers into binary, hexa, or octo.
public static void conversion (int integer, int base) {
//takes cares of the special case if the user wants to know hexidecimal
if(base <= 16) {
String calculations = Integer.toString(integer, base);
if(integer > 0 && base > 0) {
System.out.println(integer + " in binary -> " + Integer.toString(integer,
base));
}
}
}
}
You can't compare strings like that, you have to use the String object's equals() method. So, you should have:
while(!"0 0".equals(combo)) {
...
}
Notice that I've put the constant "0 0" first -- that protects you against combo being null. Otherwise you'd have !combo.equals("0 0"), and if combo were null you'd get a NullPointerException when you try to call equals() on a null value.
Try this code instead. Yours looks complicated. Btw, your code works for me.
import java.util.Scanner;
public class NewClass {
static Scanner inp = new Scanner(System.in);
static String line1 = "";
static String line2 = "";
static String exit = "exit";
public static void main(String[] args) {
System.out.println("Enter int first and then base...");
System.out
.println("Enter the word exit to exit!");
while (true) {
line1 = inp.next();
if (line1.equalsIgnoreCase(exit)) {
break;
}
line2 = inp.next();
try {
conversion(Integer.parseInt(line1), Integer.parseInt(line2));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
System.out.println("Bye...");
}
public static void conversion(int integer, int base) {
// takes cares of the special case if the user wants to know hexadecimal
if (base <= 16) {
String calculations = Integer.toString(integer, base);
if (integer > 0 && base > 0) {
System.out.println(integer + " in binary -> "
+ Integer.toString(integer, base));
}
}
}
}
I can load an object as values into an ObjectChoiceField from a sqlite database. I need an example, I get the values of the database into a vector, but the drop-down list does not accept this type single array.
clase BaseData
public Vector verSectores(){
Vector v=new Vector();
try{
URI uri=URI.create("/SDCard/Databases/app/semana_calculadora.db");
sqliteDB= DatabaseFactory.open(uri);
Statement st= sqliteDB.createStatement("select Sector from sectores_app");
st.prepare();
Cursor c= st.getCursor();
Row r;
while (c.next()){
r=c.getRow();
Sectores s= new Sectores(r.getString(0));
v.addElement(s);
}
st.close();
sqliteDB.close();
}catch(Exception e){}
return v;
}
class Result
public class Resultados extends MainScreen{
private Vector v;
public Resultados(Vector v) {
this.v = v;
for (int i = 0; i < v.size(); i++) {
Sectores s=(Sectores)v.elementAt(i);
//add(new LabelField(s.getName_sector()+ ""));
add(new SeparatorField());
}
}
as I have to pass the value of the vector to ObjectChoiceField?
class Screen
comboFormato = new ObjectChoiceField("Format:", ********, 0){
public void layout(int width, int height){
width=350;
super.layout(getWidth(), getHeight());
super.layout(width, height);
setExtent(width, super.getHeight());
}
public void paint(Graphics g) {
g.setColor(Color.RED);
super.paint(g);
}
};
You can't use a Vector as the basis of an ObjectChoiceField, but you can use an array of Objects, and it is easy to convert a Vector to an array, using, for example, facilities provided by the Arrays class or just brute force as follows:
Sectores [] array = new Sectores [v.size()];
for ( int i = 0; i < array.length; i++ ) {
array[i] = (Sectores)v.elementAt(i);
}
Now you can provide 'array' to your ObjectChoiceField, but be aware the text that the ObjectChoiceField will display for each choice, will be the String generated by using each element's toString() method.
I am using Lucene.net in my Web App.
Everithing works fine, but now i have to show the number of occurrences of my 'searchstring' in every single document of the hits array.
How can i do this? I use usual BooleanQuery.
That is my search:
BooleanQuery bq = new BooleanQuery();
bq.Add(QueryParser.Parse(Lquery, "", CurIndexDescritor.GetLangAnalizer()), false,false);
BooleanQuery.SetMaxClauseCount(int.MaxValue);
IndexSearcher searcher = new IndexSearcher(indexPath);
Hits hits = (filter != null) ? searcher.Search(bq, filter) : searcher.Search(bq);
for (int i = 0; i < hits.Length(); i++)
{
Document doc = hits.Doc(i);
SearchResultItem MyDb = new SearchResultItem();
MyDb.key = doc.Get(KeyField);
MyDb.score = hits.Score(i);
result.Add(MyDb);
}
Where can i get the number of occurrences?
Thanks!
If you dont want the score back and dont want to order the results using score you could probably build a custom Similarity implementation.
I quickly tested the following code, and it appears to work fine with TermQueries and PhraseQueries, i didnt test more query types tho. A PhraseQuery hit counts as a single occurence.
public class OccurenceSimilarity : DefaultSimilarity
{
public override float Tf(float freq)
{
return freq;
}
public override float Idf(int docFreq, int numDocs)
{
return 1;
}
public override float Coord(int overlap, int maxOverlap)
{
return 1;
}
public override float QueryNorm(float sumOfSquaredWeights)
{
return 1;
}
public override Explanation.IDFExplanation idfExplain(System.Collections.ICollection terms, Searcher searcher)
{
return CACHED_IDF_EXPLAIN;
}
public override Explanation.IDFExplanation IdfExplain(Term term, Searcher searcher)
{
return CACHED_IDF_EXPLAIN;
}
public override float SloppyFreq(int distance)
{
return 1;
}
private static Explanation.IDFExplanation CACHED_IDF_EXPLAIN = new ExplainIt();
private class ExplainIt : Explanation.IDFExplanation
{
public override string Explain()
{
return "1";
}
public override float GetIdf()
{
return 1.0f;
}
}
}
To use it:
Similarity.SetDefault(new OccurenceSimilarity());