2008年3月12日 星期三

[Imagick]圖像函式多種用法&教學

Seam carving

Mikko Koppanen February 13th, 2008

Today I was reading trough the ImageMagick ChangeLog and noticed an interesting entry. "Add support for liquid rescaling". I rushed to check the MagickWand API docs and there it was: MagickLiquidRescaleImage! After about ten minutes of hacking the Imagick support was done. Needless to say; I was excited :)

For those who don't know what seam carving is check the demo here. More detailed information about the algorithm can be found here: "Seam Carving for Content-Aware Image Resizing" by Shai Avidan and Ariel Shamir

To use this functionality you need to install at least ImageMagick 6.3.8-2 and liblqr. Remember to pass --with-lqr to ImageMagick configuration line. You can get liblqr here: http://liblqr.wikidot.com/. The Imagick side of the functionality should appear in the CVS today if everything goes as planned.

Here is a really simple example just to illustrate the results of the operation. The parameters might be far from optimal (didn't do much testing yet). The original dimensions of image are 500x375 and the resulting size is 500x200.

Update: the functionality is pending until license issues are solved.

PHP:
  1. <?php
  2. /* Create new object */
  3. $im = new Imagick( 'test.jpg' );
  4. /* Scale down */
  5. $im->liquidRescaleImage( 500, 200, 3, 25 );
  6. /* Display */
  7. header( 'Content-Type: image/jpg' );
  8. echo $im;
  9. ?>

The original image by flickr/jennconspiracy

And the result:

Update. On kenrick's request here is an image which is scaled down to 300x300



Typesetting

Mikko Koppanen January 17th, 2008

Ever had the situation where you have a piece of string which you need to overlay on an image? Maybe a situation where the area reserved for the string is known in pixels but you need to know the font size to fill most of the area? Think no more!

Here is a small example of how to fit a certain piece of a string on to an area of which you know the width and the height or only the width. The magic happens through the ImageMagick CAPTION: format. You can see from the example images how the parameters actually affect the image.

PHP:
  1. <?php
  2. /* How wide is our image */
  3. $image_width = 200;
  4. /* Give zero for autocalculating the height */
  5. $image_height = 200;
  6. /* Specify the text */
  7. $text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  8. Mauris lectus mi, mattis non, euismod vel, sagittis nec, ipsum.";
  9. /* Instanciate imagick */
  10. $im = new Imagick();
  11. /* Create new image using caption: pseudo format */
  12. $im->newPseudoImage( $image_width, $image_height, "caption:" . $text );
  13. /* Put 1px border around the image */
  14. $im->borderImage( 'black', 1, 1 );
  15. /* PNG format */
  16. $im->setImageFormat( "png") ;
  17. /* Output */
  18. header( "Content-Type: image/png" );
  19. echo $im;
  20. ?>

Here is image with width 100 and height 0:

Width 100 Height 50:

Width 200 Height 200 (as you can see the font size is now larger):



Padding thumbnail with color

Mikko Koppanen January 11th, 2008

I know, it's been a while since I last blogged. This is because a lot of things are happening in my personal life. I recently relocated to London from Finland and started a new job. Things are quite busy but I will try to post an example now and then. In the meanwhile I would like to hear about sites using Imagick, so if your project is not super secret please post an url and maybe a small explanation what you're doing with Imagick on the site. This is purely for my personal interest.

Anyway, to the point. Today's example originates from a question asked by a user. How do I thumbnail the image inside given dimensions proportionally and fill the "blank" areas with a color? Well, the answer is here :)

The code is for Imagick 2.1.0 but adapting to older versions should not be hard.

PHP:
  1. <?php
  2. /* Define width and height of the thumbnail */
  3. $width = 100;
  4. $height = 100;
  5. /* Instanciate and read the image in */
  6. $im = new Imagick( "test.png" );
  7. /* Fit the image into $width x $height box
  8. The third parameter fits the image into a "bounding box" */
  9. $im->thumbnailImage( $width, $height, true );
  10. /* Create a canvas with the desired color */
  11. $canvas = new Imagick();
  12. $canvas->newImage( $width, $height, 'pink', 'png' );
  13. /* Get the image geometry */
  14. $geometry = $im->getImageGeometry();
  15. /* The overlay x and y coordinates */
  16. $x = ( $width - $geometry['width'] ) / 2;
  17. $y = ( $height - $geometry['height'] ) / 2;
  18. /* Composite on the canvas */
  19. $canvas->compositeImage( $im, imagick::COMPOSITE_OVER, $x, $y );
  20. /* Output the image*/
  21. header( "Content-Type: image/png" );
  22. echo $canvas;
  23. ?>

The source image:

The resulting image:



Creating buttons with Imagick

Mikko Koppanen November 21st, 2007

A fellow called kakapo asked me to create a button with Imagick. He had an image of the button and a Photoshop tutorial but unfortunately the tutorial was in Chinese. My Chinese is a bit rusty so it will take a little longer to create that specific button ;)

The button in this example is created after this tutorial http://xeonfx.com/tutorials/easy-button-tutorial/ (yes, I googled "easy button tutorial"). The code and the button it creates are both very simple but the effect looks really nice.

Here we go with the code:

PHP:
  1. <?php
  2. /* Create a new Imagick object */
  3. $im = new Imagick();
  4. /* Create empty canvas */
  5. $im->newImage( 200, 200, "white", "png" );
  6. /* Create the object used to draw */
  7. $draw = new ImagickDraw();
  8. /* Set the button color.
  9. Changing this value changes the color of the button */
  10. $draw->setFillColor( "#4096EE" );
  11. /* Create the outer circle */
  12. $draw->circle( 50, 50, 70, 70 );
  13. /* Create the smaller circle on the button */
  14. $draw->setFillColor( "white" );
  15. /* Semi-opaque fill */
  16. $draw->setFillAlpha( 0.2 );
  17. /* Draw the circle */
  18. $draw->circle( 50, 50, 68, 68 );
  19. /* Set the font */
  20. $draw->setFont( "./test1.ttf" );
  21. /* This is the alpha value used to annotate */
  22. $draw->setFillAlpha( 0.17 );
  23. /* Draw a curve on the button with 17% opaque fill */
  24. $draw->bezier( array(
  25. array( "x" => 10 , "y" => 25 ),
  26. array( "x" => 39, "y" => 49 ),
  27. array( "x" => 60, "y" => 55 ),
  28. array( "x" => 75, "y" => 70 ),
  29. array( "x" => 100, "y" => 70 ),
  30. array( "x" => 100, "y" => 10 ),
  31. ) );
  32. /* Render all pending operations on the image */
  33. $im->drawImage( $draw );
  34. /* Set fill to fully opaque */
  35. $draw->setFillAlpha( 1 );
  36. /* Set the font size to 30 */
  37. $draw->setFontSize( 30 );
  38. /* The text on the */
  39. $draw->setFillColor( "white" );
  40. /* Annotate the text */
  41. $im->annotateImage( $draw, 38, 55, 0, "go" );
  42. /* Trim extra area out of the image */
  43. $im->trimImage( 0 );
  44. /* Output the image */
  45. header( "Content-Type: image/png" );
  46. echo $im;
  47. ?>

And here is a few buttons I created by changing the fill color value:



Creating a reflection

Mikko Koppanen November 19th, 2007

Here is a simple example of creating a reflection of an image. The reflection is created by flipping the image and overlaying a gradient on it. Then both, the original image and the reflection is overlayed on a canvas.

This example is created for Imagick 2.1.x but with a little tuning it should work with earlier versions.

PHP:
  1. <?php
  2. /* Read the image */
  3. $im = new Imagick( "strawberry.png" );
  4. /* Thumbnail the image */
  5. $im->thumbnailImage( 200, null );
  6. /* Create a border for the image */
  7. $im->borderImage( "white", 5, 5 );
  8. /* Clone the image and flip it */
  9. $reflection = $im->clone();
  10. $reflection->flipImage();
  11. /* Create gradient. It will be overlayd on the reflection */
  12. $gradient = new Imagick();
  13. /* Gradient needs to be large enough for the image
  14. and the borders */
  15. $gradient->newPseudoImage( $reflection->getImageWidth() + 10,
  16. $reflection->getImageHeight() + 10,
  17. "gradient:transparent-black"
  18. );
  19. /* Composite the gradient on the reflection */
  20. $reflection->compositeImage( $gradient, imagick::COMPOSITE_OVER, 0, 0 );
  21. /* Add some opacity */
  22. $reflection->setImageOpacity( 0.3 );
  23. /* Create empty canvas */
  24. $canvas = new Imagick();

  25. /* Canvas needs to be large enough to hold the both images */
  26. $width = $im->getImageWidth() + 40;
  27. $height = ( $im->getImageHeight() * 2 ) + 30;
  28. $canvas->newImage( $width, $height, "black", "png" );
  29. /* Composite the original image and the reflection on the canvas */
  30. $canvas->compositeImage( $im, imagick::COMPOSITE_OVER, 20, 10 );
  31. $canvas->compositeImage( $reflection, imagick::COMPOSITE_OVER,
  32. 20, $im->getImageHeight() + 10 );
  33. /* Output the image*/
  34. header( "Content-Type: image/png" );
  35. echo $canvas;
  36. ?>

The source image:

And the result:

P.S. Please send me some new images which I can use in these examples ;)



ImagickPixelIterator is not read-only after all..

Mikko Koppanen November 15th, 2007

A few days ago I got a help request from a user: "How do you change pixel color during the iteration with ImagickPixelIterator". My initial response was that ImagickPixelIterator is read-only.

Well, I have to admit I was wrong. After searching trough ImageMagick docs I stumbled across an example and noticed that PixelIterator (and therefor ImagickPixelIterator) is not read-only after all. I have tried the code like in this example before; without the syncIterator call after each row. After adding the Imagick::syncIterator call everything worked as expected.

This example will work with Imagick 2.1.0 (the RC1 was released yesterday) but with a little tweaking it should work with 2.0.x too.

PHP:
  1. <?php
  2. /* Create new object with the image */
  3. $im = new Imagick( "strawberry.png" );
  4. /* Get iterator */
  5. $it = $im->getPixelIterator();
  6. /* Loop trough pixel rows */
  7. foreach( $it as $row => $pixels )
  8. {
  9. /* For every second row */
  10. if ( $row % 2 )
  11. {
  12. /* Loop trough the pixels in the row (columns) */
  13. foreach ( $pixels as $column => $pixel )
  14. {
  15. /* Paint every second pixel black*/
  16. if ( $column % 2 )
  17. {
  18. $pixel->setColor( "black" );
  19. }
  20. }
  21. }
  22. /* Sync the iterator, this is important
  23. to do on each iteration */
  24. $it->syncIterator();
  25. }
  26. /* Display the image */
  27. header( "Content-Type: image/png" );
  28. echo $im;
  29. ?>

The source image:

The result image:



Color analysis

Mikko Koppanen November 5th, 2007

The idea for today's example comes from Jonathan. Jonathan was asking: "I’d like to request a tutorial. One thing I’d really like to know how to do is analyze an image for it’s color “palette”, or in other words, to find what the primary colors are that are used in an image."

I don't know if this is exactly what he meant but I hope this example can be used as a kickstart for color analysis. The code in the example reduces the image colors to 10, then discards all but one pixel of every color and then creates the palettes out of those colors. This might not be the most accurate way to do this, but at least it's fast :)

The code creates three different "palettes" from image; average palette, dark palette and bright palette. I got the idea for three different palettes from MarcosBL at freenode.

Here is the code:

PHP:
  1. <?php
  2. /* The original image is the average colors */
  3. $average = new Imagick( "test.png" );
  4. /* Reduce the amount of colors to 10 */
  5. $average->quantizeImage( 10, Imagick::COLORSPACE_RGB, 0, false, false );
  6. /* Only save one pixel of each color */
  7. $average->uniqueImageColors();
  8. /* Clone the average and modulate to brighter */
  9. $bright = $average->clone();
  10. $bright->modulateImage ( 125, 200, 100 );
  11. /* Clone the average and modulate to darker */
  12. $dark = $average->clone();
  13. $dark->modulateImage ( 80, 100, 100 );
  14. /* Helper function to create the mini-images */
  15. function createImages( Imagick $composite, Imagick $im )
  16. {
  17. /* Get ImagickPixelIterator */
  18. $it = $im->getPixelIterator();
  19. /* Reset the iterator to begin */
  20. $it->resetIterator();
  21. /* Loop trough rows */
  22. while( $row = $it->getNextIteratorRow() )
  23. {
  24. /* Loop trough columns */
  25. foreach ( $row as $pixel )
  26. {
  27. /* Create a new image which contains the color */
  28. $composite->newImage( 20, 20, $pixel );
  29. $composite->borderImage( new ImagickPixel( "black" ), 1, 1 );
  30. }
  31. }
  32. }
  33. /* This object holds the color images */
  34. $composite = new Imagick();
  35. /* Create "icons" for each palette */
  36. createImages( $composite, $dark );
  37. createImages( $composite, $average );
  38. createImages( $composite, $bright );
  39. /* Montage the color images into single image
  40. Ten images per row, three rows */
  41. $montage = $composite->montageImage( new imagickdraw(), "10x3+0+0",
  42. "20x20+4+3>", imagick::MONTAGEMODE_UNFRAME,
  43. "0x0+3+3" );
  44. /* Free some resources */
  45. $composite->destroy();
  46. /* Create an empty canvas */
  47. $canvas = new Imagick();
  48. $canvas->newImage( $montage->getImageWidth() + 55,
  49. $montage->getImageHeight(),
  50. new ImagickPixel( "white" ) );
  51. /* Display the canvas as png */
  52. $canvas->setImageFormat( "png" );
  53. /* Set font size to 12 points */
  54. $draw = new ImagickDraw();
  55. $draw->setFontSize( 12 );
  56. /* Create legends for each palette */
  57. $canvas->annotateImage( $draw, 5, 20, 0, "Dark: " );
  58. $canvas->annotateImage( $draw, 5, 45, 0, "Average: " );
  59. $canvas->annotateImage( $draw, 5, 70, 0, "Bright: " );
  60. /* Composite the montaged images next to texts */
  61. $canvas->compositeImage( $montage, Imagick::COMPOSITE_OVER, 55, 0 );
  62. /* Output the image */
  63. header( "Content-Type: image/png" );
  64. echo $canvas;
  65. ?>

Edited the example to work with 2.0.x

The first source image:

The created palette:

The second source image:

And the palette:

And one more:

Palette:



Trimming an image

Mikko Koppanen November 2nd, 2007

Especially product images usually "suffer" from this issue; the product itself is composited on a white background and there are large areas of white around the object.

This is a simple example to demonstrate how to easily trim the areas off the image and only display the parts where the object lies.

Imagick::trimImage takes one parameter which is "fuzz". Quoting ImageMagick manual: "By default target must match a particular pixel color exactly. However, in many cases two colors may differ by a small amount. The fuzz member of image defines how much tolerance is acceptable to consider two colors as the same. For example, set fuzz to 10 and the color red at intensities of 100 and 102 respectively are now interpreted as the same color for the purposes of the floodfill."

I use fuzz 0 in this example because the background color pixels are all same color.

PHP:
  1. <?php
  2. /* Create the object and read the image in */
  3. $im = new Imagick( "test.png" );
  4. /* The background color. This is what we trim. */
  5. $im->setImageBackgroundColor( new ImagickPixel( "rgb(213,213,213)" ) );
  6. /* Trim the image. */
  7. $im->trimImage( 0 );
  8. /* Ouput the image */
  9. header( "Content-Type: image/" . $im->getImageFormat() );
  10. echo $im;
  11. ?>

The source image is a simple png image with black circle on gray background:
test image

The trimmed image:
result image



Analyzing image properties

Mikko Koppanen October 26th, 2007

Imagick provides various ways to identify image properties. These properties include for example some basic attributes like width, height, format and some more advanced attributes like exif tags, profiles and colorspaces.

This example will demonstrate a few basic ways to read these attributes from an image. The image used in this example is from www.exif.org and can be found here http://exif.org/samples/fujifilm-dx10.jpg.

The support for getImageProperties and getImageProfiles was added in ImageMagick version 6.3.5-9 and Imagick version 2.0.0RC4.

PHP:
  1. <?php
  2. $im = new Imagick( "fujifilm-dx10.jpg" );
  3. $identify = $im->identifyImage();
  4. /* Ouput some basic attributes */
  5. echo '<b>Basic image properties:</b> <br />';
  6. echo 'Image geometry: ' , $identify['geometry']['width'] , 'x' , $identify['geometry']['height'] , '<br />';
  7. echo 'Image format: ' , $identify["format"] , '<br />';
  8. echo 'Image type: ' , $identify["type"] , '<br />';
  9. echo 'Image compression: ' , $identify["compression"] , '<br />';
  10. echo 'Image size: ' , $identify["fileSize"] , '<br />';
  11. echo '<br /><br />';
  12. echo '<b>All image properties:</b> <br />';
  13. /* Loop trough image properties */
  14. foreach ( $im->getImageProperties() as $k => $v )
  15. {
  16. echo $k , ' => ' , $v , '<br />';
  17. }
  18. echo '<br /><br />';
  19. echo '<b>All image profiles:</b> <br />';
  20. /* Same goes for properties */
  21. foreach ( $im->getImageProfiles() as $k => $v )
  22. {
  23. echo "Profile name: ", $k , " (size: ", strlen( $v ) ,") <br />";
  24. }
  25. ?>

The output looks something like this:

Basic image properties:
Image geometry: 1024x768
Image format: JPEG (Joint Photographic Experts Group JFIF format)
Image type: TrueColor
Image compression: JPEG
Image size: 129.955kb


All image properties:

exif:ApertureValue => 41/10
exif:BrightnessValue => -27/10
exif:ColorSpace => 1
exif:ComponentsConfiguration => ...
exif:CompressedBitsPerPixel => 14/10
exif:Compression => 6
exif:Copyright => J P Bowen
exif:DateTime => 2001:04:12 20:33:14
exif:DateTimeDigitized => 2001:04:12 20:33:14
exif:DateTimeOriginal => 2001:04:12 20:33:14
exif:ExifImageLength => 768
exif:ExifImageWidth => 1024
exif:ExifOffset => 258
exif:ExifVersion => 0210
exif:ExposureBiasValue => 0/10
exif:ExposureProgram => 2
exif:FileSource => .
exif:Flash => 1
exif:FlashPixVersion => 0100
exif:FNumber => 42/10
exif:FocalLength => 58/10
exif:FocalPlaneResolutionUnit => 3
exif:FocalPlaneXResolution => 2151/1
exif:FocalPlaneYResolution => 2151/1
exif:InteroperabilityIndex => R98
exif:InteroperabilityOffset => 708
exif:InteroperabilityVersion => 0100
exif:ISOSpeedRatings => 150
exif:JPEGInterchangeFormat => 856
exif:JPEGInterchangeFormatLength => 10274
exif:Make => FUJIFILM
exif:MaxApertureValue => 41/10
exif:MeteringMode => 5
exif:Model => DX-10
exif:Orientation => 1
exif:ResolutionUnit => 2
exif:SceneType => .
exif:SensingMethod => 2
exif:ShutterSpeedValue => 66/10
exif:Software => Digital Camera DX-10 Ver1.00
exif:XResolution => 72/1
exif:YCbCrPositioning => 2
exif:YResolution => 72/1
jpeg:colorspace => 2
jpeg:sampling-factor => 2x1,1x1,1x1
Signature => 434d8554488bf9af5fc551adeba43e6d1d04ac36559a02357cf5df93db4b35c5

All image profiles:
Profile name: exif (size: 11136)




摘自:http://valokuva.org/?cat=1

2008年3月10日 星期一

[CakePHP]CakeSession needs support to set cookies over ALL subdomains

Description
I have a site where I need to preserve cookies over all sub-domains. Since it is quite useless to set the domain of a cookie to another domain (since browsers won't allow that) just allowing a flag to cover all subdomains might be useful.

Core...


define('CAKE_SESSION_SUBDOMAINS', true);


in cake/libs/session.php function initSession()

switch($this->security) {
case 'high':
$this->cookieLifeTime=0;
if (function_exists('ini_set')) {
ini_set('session.referer_check', $this->host);
}
break;
case 'medium':
$this->cookieLifeTime = 7 * 86400;
break;
case 'low':
default:
$this->cookieLifeTime = 788940000;
break;
}

//subdomain code
if (CAKE_SESSION_SUBDOMAINS){
if (substr_count ($this->host, ".") == 1){
cookie_domain = "." . $this->host;
}else{
$cookie_domain = preg_replace ('/^([^.])*/i', null, $this->host);
}
ini_set ("session.cookie_domain", $cookie_domain);
}
//end subdomain code


摘自:https://trac.cakephp.org/ticket/830

2008年3月5日 星期三

[FreeBSD]利用 pw 指令來增加/變換 user 的 group

例:帳號 abcd 所屬群組 abcd

變換帳號 abcd 的預設群組為 staff (當然得要先有 staff 這個群組)

$ pw user mod -n abcd -g staff
$ groups abcd
staff


變換帳號 abcd 的預設群組為 office,並加入到 www,mysql,squid 三群組中

$ pw user mod -n abcd -g office -G www,mysql,squid
$ groups abcd
office www mysql squid


不變換預設群組,只將帳號 abcd 加入到 office,staff,game,software 四群組中

$ pw user mod -n abcd -G office,staff,game,software
$ groups abcd
abcd www mysql squid


將帳號 abcd 維持在預設群組中,並從其它附屬的群組中移除

$ pw user mod -n abcd -G ""
$ groups abcd
abcd

[FreeBSD]關於 Proftpd 設定 DefaultRoot

原來 DefaultRoot可以重複設,比如:


DefaultRoot ~ ice_gogogo
DefaultRoot /srv/

就是設定「除了ice_gogogo這個群組登入後到自己家目錄,其餘皆會 chroot 到 /srv」。採取的規則是 first match ,所以要是反過來設就會有不一樣的結果。

摘自:http://williewu.blogspot.com/2007/03/proftpd-defaultroot.html

2008年3月4日 星期二

[教學] Ramdisk 簡易按裝圖文教學與自動備份製作

首先下載 Ramdisk Rainwen大提供的連結 http://www.badongo.com/file/7201826

安裝程式


系統設定


製作開關機備份


系統資訊



以上內容如有出錯煩請告知

Ramdisk實際測試
http://www.pcdvd.com.tw/showthread.php?p=1080721014


摘自:http://www.pcdvd.com.tw/showthread.php?t=771727

[病毒]KAVO,熊貓燒香

前一陣子電腦中了毒,經過一番爬文後發現這應該是「KAVO隨身碟病毒」

症狀是雙擊C、D槽都無法直接開啟,且還有被詢問要用什麼程式來開啟C、D槽的怪事

此症狀中了「熊貓燒香」時也會有

但熊貓燒香還有個特徵,那就是會讓電腦中副檔名為.exe的應用程式圖示變成這樣

不過我只有無法開啟硬碟而已

今天和我的傀儡聊天,發現他家電腦和公司電腦也出現了跟我之前一樣的情形

我才知道原來這個病毒近來這麼夯!(雖然都醫好了,但我中了不止一次)

這種隨身碟病毒,在你把受感染的隨身碟插進電腦中時,即立刻蔓延至所有其它電腦中的磁碟

凡是某磁碟打不開;打開後從另一個視窗跳出來,或是無法顯示隱藏檔都屬於不正常現象

甚至電腦中一些軟體打開後立刻關閉,譬如我的Yahoo即時通、迅雷等等程式

另外在WINDOWS\system32資料夾裡,會有Kavo.exe及Kavo01.dll兩個偽裝成系統檔的檔案

並且關閉資料夾選項內顯示所有隱藏檔的功能,目的就是要讓人看不見它

見下圖,在控制台中"資料夾選項"的"檢視"標籤(依樣式不同,資料夾選項也許在"外觀和主題"內)

選了"顯示所有檔案和資料夾"按確定後,再回來看一次,如果它又自己跳回來那你就是中毒了



意義就是為了不讓你看到或刪除掉Kavo.exe及Kavo01.dll


解決之道:

首先在我的電腦按右鍵>內容>系統還原標籤,打勾"關閉所有磁碟上的系統還原"後按確定

接著點此下載kavo_killer.exe(感謝原作 張書維),下載後執行

直接按上方"開始清除",此時你可以再回資料夾選項看看是不是已經可以"顯示所有檔案和資料夾"了



「傳說拔掉熊貓的懶毛就可以找回遺失的C槽」,別再相信沒有根據的說法了

請再點此下載開啟所有磁碟.bat

此批次檔會幫助你開啟所有C到Z的磁碟(不管你有沒有),如此一來所有硬碟就能順利開啟了!

摘自:http://www.wretch.cc/blog/davydie&article_id=9076589

2008年3月1日 星期六

Excel讀取CSV數值字串的解決方法

在產生讓Excel讀取的CSV(Comma Separated Values)檔案時,由於Excel的自動轉換功能,導致想要保持原樣的欄位也被強迫轉錯了。例如字串的"00123"會被Excel自動轉成數值的 123。真是傷腦筋。

還好,最後在這裡找到解決方法。原來只要加上等號就可以了,也就是是把 "00123" 寫成 ="00123" 就解決了。

摘自:http://blog.roodo.com/emisjerry/archives/2598976.html

wibiya widget