2010-07-08 29 views
5

Hey folks, Tôi đang làm việc trên một trò chơi j2ME cho java có khả năng điện thoại di động. Tôi đang cố gắng mở rộng PNG trong suốt theo phương pháp sau:Phương pháp tùy chỉnh để rescale một PNG mất tính minh bạch

// method derived from a Snippet from http://snippets.dzone.com/posts/show/3257 
// scales an image according to the ratios given as parameters 

private Image rescaleImage(Image image, double XRatio, double YRatio) 
{ 
    // the old height and width 
    int sourceWidth = image.getWidth(); 
    int sourceHeight = image.getHeight(); 

    // what the new height and width should be 
    int newWidth = (int)(XRatio * sourceWidth); 
    int newHeight = (int)(YRatio * sourceHeight); 

    Image newImage = Image.createImage(newWidth, newHeight); 
    Graphics g = newImage.getGraphics(); 

    for (int y = 0; y < newHeight; y++) 
    { 
     for (int x = 0; x < newWidth; x++) 
     { 
      g.setClip(x, y, 1, 1); 
      int dx = (x * sourceWidth)/newWidth; 
      int dy = (y * sourceHeight)/newHeight; 
      g.drawImage(image, (x - dx), (y - dy), Graphics.LEFT | Graphics.TOP); 
     } 
    } 
    return Image.createImage(newImage); 
} 

Tỷ lệ hình ảnh chính xác, rất tiếc là tôi dường như mất tính minh bạch với hình ảnh được phương thức trả về. Tôi khá mới mẻ với những khái niệm này, và bất kỳ sự trợ giúp nào cũng sẽ được đánh giá cao! Xin lưu ý rằng để được hiển thị chính xác trên bất kỳ thiết bị di động có khả năng java nào, việc rescaling cần được thực hiện bằng mã, không phải trong bất kỳ loại trình chỉnh sửa hình ảnh nào.

Cảm ơn trước!

Trả lời

4

Nhờ tất cả những người đã tìm kiếm các giải pháp cho vấn đề dường như lan rộng và chưa được giải quyết này. Tôi đã tìm được giải pháp tuyệt vời tại http://willperone.net/Code/codescaling.php

Bạn chỉ cần thay đổi "false" trong tham số createRGBImage thành true. Đây là phương pháp để xử lý các bit có thứ tự cao của mỗi pixel dưới dạng giá trị alpha. Đây là triển khai của tôi, không có nhiều thay đổi so với liên kết gốc ở trên.

XRatio và YRatio được khai báo là hằng số khi canvas được khởi tạo, trong đó XRatio = this.getWidth() (chiều rộng màn hình của điện thoại hiện tại) chia cho chiều rộng hình nền ban đầu của bạn và YRatio với getHeight()/hình nền gốc Chiều cao.

// RESCALEIMAGE 
// scales an image according to the ratios given as parameters 
// derived from http://willperone.net/Code/codescaling.php 

public static Image rescaleImage(Image original, double XRatio, double YRatio) 
{ 
    // the original width and height 
    int originalWidth = original.getWidth(); 
    int originalHeight = original.getHeight(); 

    // the target width and height 
    int newWidth = (int)(XRatio * originalWidth); 
    int newHeight = (int)(YRatio * originalHeight); 

    // create and fill the pixel array from the original image 
    int[] rawInput = new int[originalHeight * originalWidth]; 
    original.getRGB(rawInput, 0, originalWidth, 0, 0, originalWidth, originalHeight); 

    // pixel array for the target image 
    int[] rawOutput = new int[newWidth*newHeight]; 

    // YD compensates for the x loop by subtracting the width back out 
    int YD = (originalHeight/newHeight) * originalWidth - originalWidth; 
    int YR = originalHeight % newHeight; 
    int XD = originalWidth/newWidth; 
    int XR = originalWidth % newWidth; 
    int outOffset= 0; 
    int inOffset= 0; 

    for (int y = newHeight, YE = 0; y > 0; y--) 
    { 
     for (int x = newWidth, XE = 0; x > 0; x--) 
     { 
      rawOutput[outOffset++] = rawInput[inOffset]; 

      inOffset += XD; 
      XE += XR; 

      if (XE >= newWidth) 
      { 
       XE -= newWidth; 
       inOffset++; 
      } 
     } 

     inOffset += YD; 
     YE += YR; 

     if (YE >= newHeight) 
     { 
      YE -= newHeight; 
      inOffset += originalWidth; 
     } 
    } 
    return Image.createRGBImage(rawOutput, newWidth, newHeight, true); 
} 
1

Có thể do bạn không phân biệt alpha trong giá trị pixel. Những gì bạn có thể làm là thêm một thói quen bổ sung để xử lý những người có alpha để họ giữ các giá trị alpha có thể của họ. Về cơ bản, nó kiểm tra mọi pixel, xem nó có alpha hay không, nếu có, kiểm tra xem nó có nằm trên hình ảnh đã được chỉnh lại kích cỡ hay không, nếu có, hãy áp dụng nó ở đó với alpha, nếu không, hãy loại bỏ nó.

+0

Cảm ơn Yonathan. Tôi đang cố gắng sử dụng Image.GetRGB() và Image.createRGBImage() cùng với thuật toán mở rộng để thao tác mảng ARGB ở giữa. Chúc các bạn may mắn :) – jbabey

+0

Cập nhật về cách tiếp cận ARGB: Nó hoạt động khá tốt, ngoại trừ thực tế là tỷ lệ chia tỷ lệ thường không phải là số nguyên, làm cho thao tác mảng pixel thuần túy khó hơn một chút. – jbabey

Các vấn đề liên quan