If you are sure that it isn't actually an instance of BufferedImage then
you need to create a BufferedImage and draw your Image on it. Then save
the BufferedImage to a file with the ImageIO class. If it is really a
BufferedImage then just save it.
--
Knute Johnson
email s/nospam/knute/
See http://www.rgagnon.com/javadetails/java-0266.html .
Bye.
--
Real Gagnon from Quebec, Canada
* Looking for Java or PB code examples ? Visit Real's How-to
* http://www.rgagnon.com/howto.html
//img is an Image object whose height and width are
public void saveJPG(){
// Write generated image to a file
BufferedImage buffered =
makeBufferedImage(img,BufferedImage.TYPE_INT_RGB);
}
public static BufferedImage makeBufferedImage( Image image, int type
){
BufferedImage buffered;
Graphics2D g2;
//buffered = new BufferedImage(width,height,type);
buffered = new BufferedImage( image.getWidth( null ),
image.getHeight( null ),
type );
g2 = buffered.createGraphics();
g2.drawImage( image, null, null );
return( buffered );
JIMI is a old library for 1.1.x .
The more current library is JAI (java image io api). But for your purpose
JIMI should be good enough and simpler to use.
You can download the JIMI package from http://java.sun.com/products/jimi/
Since you are talking about Applet, I hope that you realize that you won't
be able to save the JPG on the client unless the Applet is signed.
Do I need to download a separate package? This would mean that every
client would need to download a package. Is there any reasonable image
type that comes with the standard java libraries?
What is it you are really trying to do? Are you trying to get your
Applet to write to the local disk? This is going to be problematic.
Are you trying to send an image from the Applet to a server on the
machine that the Applet came from? If so your server should just read a
stream from the applet. Convert your BufferedImage to a byte array and
write it to the server. On the server end if you want to save the
BufferedImage as a JPEG file for example, just write it to disk with the
ImageIO.write().
If either of those options aren't what you are trying to do, just let us
know.
I don't really know how to program servlets or JSP, so I just want my
php script to handle the server side, and that's why I probably can't
use a stream. Or maybe they're compatible somehow and I can do a
stream...?
Also, it seems that every client needs a JPG java package if they want
to use such an applet. Is this a fair assessment? If so, I am willing
to look into other image file types.
Create a BufferedImage and draw on it.
> -The applet to upload the jpg to a program on my server maybe in a POST
> request
You can either do the HTTP connection with Sockets and Streams or use
the HTTPURLConnection class. Write the BufferedImage to your server
with the ImageIO.write() in JPEG format.
> -My program to process the jpg
I've never used PHP but I have processed form data with Perl. You
should be able to read the data and write it to a file with no problems
as it will already be in JPEG file format.
>
> I don't really know how to program servlets or JSP, so I just want my
> php script to handle the server side, and that's why I probably can't
> use a stream. Or maybe they're compatible somehow and I can do a
> stream...?
I don't either but I don't know why you couldn't use a stream.
> Also, it seems that every client needs a JPG java package if they want
> to use such an applet. Is this a fair assessment? If so, I am willing
> to look into other image file types.
I don't think so. JPEG is just a file format. The file is still an
array of bytes. If you send your server an array of bytes that is an
image of a JPEG file then you can just write the bytes to a file and
you're done.
Why don't you write your server in Java?
So what I'd like to know is:
-is it actually true that I would have to make clients download a jpg
java package if I wanted the applet to convert the BufferedImage?
-Do you or does anyone have a nice method that converts a BufferedImage
to jpg or other format?
-how exactly would I use the HTTPURLConnection class or ImageIO class
in that manner?
I am so new to Java that small details will be greatly appreciated.
Thanks!
No. They will however have to have a modern version of the Java Runtime
Environment. Version 1.4 or later.
> -Do you or does anyone have a nice method that converts a BufferedImage
> to jpg or other format?
The ImageIO class has methods that will write a BufferedImage to a file
or stream in JPEG format.
> -how exactly would I use the HTTPURLConnection class or ImageIO class
> in that manner?
You need to look at the docs. I would download a copy but you can look
at them on the web here:
http://java.sun.com/j2se/1.5.0/docs/index.html
> I am so new to Java that small details will be greatly appreciated.
> Thanks!
This is a pretty sophisticated undertaking for not knowing much about
the language. You could write your client in C++ too. I think Java is
easier but that is just my opinion.
Is your Applet going to be some sort of drawing program or ? I would
start with that part first. Start writing your Applet and get it to the
point that you can create your JPEG image then worry about how to get it
to your server. Look at the docs.
Would I use something similar to this function I found? I already have
a bufferedImage, so I can pick it up from there
public imageConvert() {
try {
BufferedImage b = ImageIO.read(new File("img1.gif"));
ImageIO.write(b,"JPEG",new File("img1.jpg"));
} catch (IOException e) {
System.out.println(e);
}
}
So I would just use ImageIO.write(b,"JPEG",new File(filename));
And then I will figure out the httpconnection thing.
No.
> Lee wrote:
>> No wait I can't use the File parameter. I need to find something like
>> JPEG jpg = ImageIO.write(myBufferedImage,"JPEG");
>> Does this method exist or something similar? I couldn't really find
>> something like this under ImageIO.
>>
If you looked at the docs you would have seen the
ImageIO.write(RenderedImage im, String formatName, OutputStream output).
You need to look at the URL class, the URLConnection class and the
HTTPURLConnection class. There are methods to get the InputStream and
OutputStream (this is what you want) and to set the request method.
Once you have things set up just write the image to the OutputStream.
Rather than drawing a dot at the mouse location when the button is down,
how about drawing a line from the previous location to the current location,
so there's less of a "leaky, drippy pen" effect?
- Oliver
One quick question: why is it not giving an error when I use a
BufferedImage instead of a RenderedImage? Is it casting it
automatically?
//create JPG in memory and upload it
public void saveJPG(){
BufferedImage buffered =
makeBufferedImage(backbuffer,BufferedImage.TYPE_INT_RGB);
String domain = "www.lskatz.com";
String file = "xxxx/xxxx/upload.php";
try{
URL uploadPageURL = new URL("http", domain, 80, file);
HttpURLConnection urlConnection =
(HttpURLConnection)uploadPageURL.openConnection();
urlConnection.setRequestMethod("POST");
OutputStream output = urlConnection.getOutputStream();
ImageIO.write(buffered, "jpg", output); //need RenderedImage
}
catch (IOException e) {}
Lee:
That's what I had in mind, yes. I don't know if POST requires any other
header information or not. You appear to know how that works though.
What I did was make a php script that creates a file and writes some
information about any file data, post data, or get data (I did test
this script to make sure it worked). However, using that method
saveJPG does not activate the script at all and so it is not connecting
to it.
How should I begin troubleshooting it? Or is there a good resource on
the URL classes and how to transfer files?
Lee:
The first thing I would do is make sure that it is possible to connect
to your script. Use telnet to try to talk to your script. If that
works, write a simple script that will print out status information from
the connection with your java client. The Java Applet must be served up
from the same machine that you are trying to connect to.
String img = convertJPGToString();
URL yahoo = new URL ("http://www.yahoo.com/?img=" + img);
Once my PHP script gets the img String like this, it can take over. I
think that I might be able to accomplish it with the
JPEGImageWriteParam class but I'm not sure how.
/////////////////////////////////////////////////////////////////
import java.net.*;
import java.io.*;
public class URLConnectionReader {
public static void main(String[] args) throws Exception {
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
A POST command looks like the following:
POST /cgi-bin/myscript.php HTTP/1.0
.
. header info
.
Content-Length: 10
0123456789
You should be able to open the URLConnection, write the headers and then
the content out the output stream. Your script will get handed the
content length and the data. You just read the data and write it to a file.
Exception in thread "AWT-EventQueue-1"
java.security.AccessControlException: access denied
(java.net.SocketPermission www.lskatz.com:80 connect,resolve)
//////////////////////////////////////////////////////////////////////////////////
try{
URL uploadPageURL = new URL(path);
HttpURLConnection urlConnection =
(HttpURLConnection)uploadPageURL.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
OutputStream output = urlConnection.getOutputStream();
//ImageIO.write(buffered, "jpg", output); //need RenderedImage
}
catch (IOException e) {
backg.drawString(e.getMessage(),50,50);
Hi Lee,
Don't know whether or not you still need it, but here are two options for
saving an image to jpeg or gif.
http://jcsnippets.atspace.com/java/gui-graphics/create-thumbnail.html
http://jcsnippets.atspace.com/java/gui-graphics/create-thumbnail-with-option
s.html
Best regards,
JayCee
--
http://jcsnippets.atspace.com/
a collection of source code, tips and tricks
An Applet can only connect to the machine that served it up. Are you
getting your Applet from www.lskatz.com?
The exception that I get returned with the command
catch (IOException e) {
backg.drawString(e.getMessage(),50,50);
}
is
no protocol: images/graffiti.jpg
where images/graffiti.jpg is the path I gave as the URL and
graffiti.jpg is a file I uploaded with chmod 777.
Where did I go wrong?
Lee:
I need more of the code than that to tell you. Why would you have a URL
of a JPEG file? The only URL should be the URL of your PHP script.
Is it writing a jpg to a file?
or
Is it making a post request? If it is a post request, I need a
key/value, which means I need to convert the jpg to a string.
My thought was that the POST request was just to get it to talk to your
PHP script. If you send it the length of the data in the header and
then just read the bytes and write them to your JPEG file you should be
good to go. What I didn't think about is that I'm not sure that you can
write 8bit bytes.
// pseudo code
So if you write to the URL output stream:
POST /cgi-bin/urscript.pl HTTP/1.0
Content-Length: ???
// then write the image here with ImageIO.write()
On the script end:
read (STDIN,$form_info,$size_of_data); // read the data
write(JPEG,$form_info); // write it to local file
But thinking about it now I am concerned that you may not be able to
write 8 bit data to your script. Do you know? If not you will need to
UUENCODE it first. Use the ImageIO.write() to write the data to a
ByteArrayOutputStream, then UUENCODE it, and then write it out the URL
output stream. On the other end you will need to UUDECODE it back to 8
bit data.
The ByteArrayOutputStream looks promising, but I'm really new to java,
and I don't understand it too well. Wouldn't it give me the same
trouble since it is a subclass of outputstream?
Also, what is UUENCODE?
I really wish java made the steps easier to do: save a jpg in memory,
convert it to a string, and then send a request.
See http://schmidt.devlib.org/java/image-faq/read-write-image-files.html
It says "file", but http://schmidt.devlib.org/java/save-jpeg-thumbnail.html
has an example of writing to a BufferedOutputStream, which can be redirected
anywhere (e.g. across a socket).
> Also, what is UUENCODE?
There's a wikipedia article on that topic.
- Oliver
You can send 8 bit bytes. You need to specify the content type though.
See http://developers.sun.com/techtopics/mobility/midp/ttips/HTTPPost/
- Oliver
The current issues I am thinking about are the following:
how can I convert a jpg to a string and then create a post request?
Or, is it possible to make an OutputStream over the Internet to simply
create a file? Does an OutputStream create a new file or does it write
over a preexisting file? How do applet restrictions affect this
OutputStream method?
Lee:
I've been playing with this way too much but I have a simple solution
for you.
Here is an Applet to create an image and send it to the HTTP server:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import javax.imageio.*;
public class test extends Applet {
public void init() {
Button b = new Button("submit6");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
showStatus("button pressed");
try {
BufferedImage bi =
new
BufferedImage(100,100,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.BLUE);
g.drawLine(0,0,100,100);
ByteArrayOutputStream baos = new
ByteArrayOutputStream();
ImageIO.write(bi,"JPEG",baos);
byte[] buf = baos.toByteArray();
URL url = new URL(
"http://rabbitbrush.frazmtn.com/cgi-bin/savjpg.pl");
HttpURLConnection con =
(HttpURLConnection)url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestMethod("POST");
OutputStream os = con.getOutputStream();
os.write(buf);
os.flush();
os.close();
InputStream is = con.getInputStream();
int c;
while ((c = is.read()) != -1)
System.out.write(c);
System.out.println();
is.close();
os.close();
con.disconnect();
} catch (Exception e) {
showStatus(e.toString());
}
}
});
add(b);
}
}
And here is a perl script (you should be able to adapt this to PHP with
no trouble) to read the image data and write it to a file.
#!/usr/bin/perl
binmode STDIN; # i'm not sure this is necessary
open TEST, ">/tmp/test.jpg" or die "can't open file";
binmode TEST;
while (<STDIN>) {
print TEST;
}
close TEST;
print STDOUT "Content-type: text/plain\n\n";
print STDOUT "thanks\n";
exit;
These work on my Fedora Core 5 server. If you need my selinux settings
let me know.
This would be very easy if you would write the server in Java too.
There are many ways. One of them is UUENCODE. Another is Base64. You can
invent your own system too.
> Or, is it possible to make an OutputStream over the Internet to simply
> create a file? Does an OutputStream create a new file or does it write
> over a preexisting file?
The are the "wrong" questions to ask. OutputStream doesn't really have
anything to do with files, per say. An OutputStream is just something you
can send data to from your Java code. It can go anywhere you want. You could
have it go to a file, or to an byte array in memory, or over the Internet,
etc.
If you're sending it over the internet, it's probably going to travel as
TCP/IP packets, and within TCP/IP there also is no concept of "file". You
just have a client and a server, and in your case your client (written in
Java) is sending packets to the server (written in PHP).
What the server does with the data in that packet is entirely up to the
server. It could save the data to a file, or it could do some translation on
the data first, then save it to a file, or it could use the data to generate
an e-mail, or ignore the data completely, etc.
In your case, you probably want to save the data to a file.
> How do applet restrictions affect this
> OutputStream method?
Unless the applet is signed, it can only connect to the server that
hosted it. So if you put the applet on http://foo.com/ then your applet can
only connect to http://foo.com/, and not http://bar.com/ for example.
If you sign the applet, it can connect anywhere, but a security message
will pop up asking the user if they are willing to trust your signature.
- Oliver
PHP doesn't have a "binmode" command/statement/whatever. The equivalent
(I'm guessing, since I don't know for *sure* what binmode does) would be to
call fopen() with the binary flag. See
http://ca.php.net/manual/en/function.fopen.php and
http://ca.php.net/manual/en/function.fwrite.php and pay attention to the
user comments which talk about troubles surrounding writing binary data.
As for STDIN, my first gut feeling is that you should be reading from
$_POST, but this is associative array, which implies that you need a
name-value pair, and not just the value (being the JPG file). The OP may
wish to look at http://ca.php.net/manual/en/features.file-upload.php and
modify the Java applet correspondingly to format the POST request in the
appropriate manner (passing in the mime/type, size, original name of the
file on client machine, etc.)
- Oliver
Yes I was thinking the same thing about $_FILES. In PHP, you need an
associative array with key-value pairs, and as far as I know, there is
nothing similar to the command line arguments. But in PERL, you have
command line stuff. Actually, Knute's idea to use perl might actually
be the better way to process the file when it comes in just because of
the stream handling.
I am going to test the code out with $_FILES anyway just in case I
might be able to get away with using PHP.
Lee:
I wish I knew something about PHP to help you but I don't :-). There
are some packages in Perl (that I didn't use here) to handle sending
files to cgi programs. I assume there must be similar things in PHP.
You know that this would be a trivial exercise to write the server in Java?
I wrote this PHP script as the receiving script and it gave me the
following output. For some reason, it is reading in the stream as a
blank input. But anyway, if you have a java script for me to use
somehow, I'd certainly try it. I just don't think I'm capable of
making it for myself.
======================
STDIN content
11:13:50
=====================
<?
// open the log file
$filename='log.txt';
$fp=fopen($filename,'w+');
// see which kind of input I'm getting
if($_FILES){
$str="files\n\n" . print_r($_FILES,true);
}
elseif($_POST){
$str="post\n\n" . print_r($_POST,true);
}
elseif($_GET){
$str="get\n\n" . print_r($_GET,true);
}
elseif(STDIN){
$max=1*10^6;
$stdin = fopen('php://stdin', 'r');
$content = fread($stdin,$max);
$str="STDIN content\n\n" . $content;
}
else{
$str="no files found";
}
// write to the log file
$str .= "\n\n" . date('G:i:s',time());
fwrite($fp,$str);
fclose($fp);
// display the log file
header("Content-type: text/plain");
include $filename;
?>
import java.net.*;
import java.io.*;
import java.util.Scanner;
class PostRequest{
private String path;
private String request="&"; // the request string
private String outputPage=""; // the page that is returned
// getters
public String getPath(){
return path;
}
public String getRequest(){
return request;
}
public String getOutputPage(){
return outputPage;
}
// setters
public void setPath(String path){
this.path = path;
}
// add key/value pairs for the request
public void addRequest(String key, String value){
this.request += key + "=" + value + "&";
}
public void connect(){
try{
URL url = new URL(path);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches (false);
con.setRequestMethod("POST");
// write the parameters
OutputStreamWriter out = new
OutputStreamWriter(con.getOutputStream());
// Send data to host
String data = this.getRequest();
out.write(data, 0, data.length());
out.close();
// read the file that was written to
InputStream is = con.getInputStream();
Scanner pageScanner = new Scanner(is);
while (pageScanner.hasNext()){
outputPage += pageScanner.nextLine() + "\n";
}
is.close();
con.disconnect();
}
catch(IOException e){
System.out.println("error: " + e.getMessage() + "\n\n" + e + "\n" +
path);
}
}
// constructor
public PostRequest(){
}
public static void main (String[] args){
PostRequest postRequest = new PostRequest();
String path = "http://example.com/something.php";
postRequest.setPath(path);
postRequest.addRequest("php","cool");
postRequest.addRequest("Java","difficult");
postRequest.connect();
System.out.println (postRequest.getOutputPage());