Hello All,
I am new to writing plugins and am trying to read a raw file in through a plugin. I have several questions: 1. Each file I am reading is 105906380 bytes long. It takes a while to read the file. How can I speed it up? I am currently reading the file slice by slice via these commands: for (int s=0;s<slices;s++){ img.setSlice(s+1); IJ.showProgress( (double) s / slices); pixels = (short[]) img.getProcessor().getPixels(); for(int row=0;row<height;row++){ offset = (row*width); for (int col=0;col<width;col++){ pixels[offset+col]=swapshort(input.readShort()); } } } 2. I would like to scale the pixel value linearly. However when I change one line line from the above snipped to : pixels[offset+col]=swapshort(input.readShort()-16383); I get an error message "Incompatible type for method. Explicit cast needed to convert int to short.". How do I operate on pixel element values. Many thanks. KB |
Kb Pru wrote:
> pixels[offset+col]=swapshort(input.readShort()); > Reading pixel-by-pixel may take forever unless you use a buffered input stream. > 2. I would like to scale the pixel value linearly. However when I change one > line line from the above snipped to : > pixels[offset+col]=swapshort(input.readShort()-16383); > I get an error message "Incompatible type for method. Explicit cast needed > to convert int to short.". How do I operate on pixel element values. > In java, arithmetic operations go up to int or to double. In your case to int. So cast the result back to short: pixels[offset+col]= swapshort( (short) (input.readShort()-16383) ); Overall, you may be better off using LOCI Bioformats, which you may extend for your particular file format and which have virtual stack (read: dynamic loading) capabilities. Albert -- Albert Cardona http://albert.rierol.net |
Thanks. With
pixels[offset+col]= swapshort( (short) (input.readShort()-16383) ); there is no error, but I still do not see a subtraction in the displayed image values. Can you please point me to some documentation about buffered input stream you talk about? I did mention I am new to javascript! :) My entire code is as follows: import java.io.*; import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; import ij.io.*; import ij.measure.*; import java.lang.*; public class Open_V3d implements PlugIn { public void run(String arg) { String name;String directory = ""; // Open dialog to pick a v3d file OpenDialog od = new OpenDialog("Load V3d file...",arg); name = od.getFileName(); directory = od.getDirectory(); if (name == null) return; IJ.showStatus(directory+name); // Open v3d file try { FileInputStream fs = new FileInputStream(directory+name); DataInputStream input = new DataInputStream( new BufferedInputStream(fs) ) ; int width,height,slices,element,offset; short pixels[]; long filesize=0,StartReadPos=0; short pixelscaling = 16383; //Skip first 40 bytes to read the dimensions input.skipBytes(40); width = swap(input.readInt()); height = swap(input.readInt()); slices = swap(input.readInt()); //Calculate where we have to start reading the file for data filesize = fs.getChannel().size(); StartReadPos = filesize - (width*height*slices*2)-(40+(3*4)); input.skipBytes((int)StartReadPos); //IJ.showMessage("OpenV3d",""+StartReadPos); ImagePlus img = IJ.createImage("v3dFile","16-bit",width,height,slices); // Reading pixel by pixel. Probably not very efficient. Change later. for (int s=0;s<slices;s++){ img.setSlice(s+1); IJ.showProgress( (double) s / slices); pixels = (short[]) img.getProcessor().getPixels(); for(int row=0;row<height;row++){ offset = (row*width); for (int col=0;col<width;col++){ //pixels[offset+col]=swapshort(input.readShort()-pixelscaling); pixels[offset+col]=swapshort((short) (input.readShort()-pixelscaling) ); } } } img.show(); input.close(); } catch (IOException e) { IJ.write("FileLoader: " + e.getMessage()); } } public static int swap (int value){ int b1 = (value >> 0 ) & 0xff; int b2 = (value >> 8 ) & 0xff; int b3 = (value >> 16) & 0xff; int b4 = (value >> 24) & 0xff; return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0; } public static short swapshort (short value){ int b1 = value & 0xff; int b2 = (value >> 8) & 0xff; return (short) (b1 << 8 | b2<<0); } } On Tue, Jun 2, 2009 at 9:46 AM, Albert Cardona <[hidden email]>wrote: > Kb Pru wrote: > >> pixels[offset+col]=swapshort(input.readShort()); >> >> > > > Reading pixel-by-pixel may take forever unless you use a buffered input > stream. > > > 2. I would like to scale the pixel value linearly. However when I change >> one >> line line from the above snipped to : >> pixels[offset+col]=swapshort(input.readShort()-16383); >> I get an error message "Incompatible type for method. Explicit cast needed >> to convert int to short.". How do I operate on pixel element values. >> >> > > > In java, arithmetic operations go up to int or to double. In your case to > int. > So cast the result back to short: > > pixels[offset+col]= swapshort( (short) (input.readShort()-16383) ); > > > Overall, you may be better off using LOCI Bioformats, which you may extend > for your particular file format and which have virtual stack (read: dynamic > loading) > capabilities. > > Albert > > -- > Albert Cardona > http://albert.rierol.net > |
On 2 Jun 2009, at 16:20, KB wrote:
> Can you please point me to some documentation about buffered input > stream > you talk about? I did mention I am new to javascript! :) > Hava a look at java.sun.com; there you find all java documentation, e.g., http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html DataInputStream has the advantage that it reads signed as well as unsigned short, but the disadvantage that the overhead of a method call for each short makes it significantly slower than methods that return arrays. Your current code extracts bytes from the short data to swap the bytes. It would be faster to read the bytes for a row of pixels or the whole image into an array (InputStream can fill a byte buffer) and then compose the shorts from the bytes array. Michael |
In reply to this post by Kb Pru
Kb,
the easiest way in my option is to use the Import > Raw available into IJ. If you are intended to use it inside of a plugin, you can directly instanciate the Import class and call its execution from your code. Another optiion is to use the "Record Macro" resource and open one image using the File > Import > Raw command and after this, get the plugin or macro code from this operation. I hope this helps you. Best regards, Fernando On Tue, Jun 2, 2009 at 10:26 AM, Kb Pru <[hidden email]> wrote: > Hello All, > I am new to writing plugins and am trying to read a raw file in through a > plugin. I have several questions: > > 1. Each file I am reading is 105906380 bytes long. It takes a while to read > the file. How can I speed it up? I am currently reading the file slice by > slice via these commands: > > for (int s=0;s<slices;s++){ > img.setSlice(s+1); > IJ.showProgress( (double) s / slices); > pixels = (short[]) img.getProcessor().getPixels(); > for(int row=0;row<height;row++){ > offset = (row*width); > for (int col=0;col<width;col++){ > pixels[offset+col]=swapshort(input.readShort()); > } > } > } > > 2. I would like to scale the pixel value linearly. However when I change > one > line line from the above snipped to : > pixels[offset+col]=swapshort(input.readShort()-16383); > I get an error message "Incompatible type for method. Explicit cast needed > to convert int to short.". How do I operate on pixel element values. > > Many thanks. > > KB > |
Free forum by Nabble | Edit this page |